奔跑中的奶酪

奔跑中的奶酪 有智,有趣,有爱
当前位置 - 首页 - Firefox - Firefox 火狐不完全开发手册

Firefox 火狐不完全开发手册

奔跑中的奶酪  发表于:2018-03-19  326052次浏览  6条评论 

  • 导读



    国内有关于Firefox开发的教程少之又少,要么全是英文的,要么太过官方,要么过于老旧,要么过于零散,所以我整理了一份详实接地气的 Firefox 开发手册,包括了开发案例,源代码和源文件,还包括了火狐相关的优秀网站和开发者,希望可以给喜欢 Firefox 的人一些参考, Firefox 有你的加入会变得更好。
  • 开发指南

    开发流程

    随着新版 Firefox 启用了全新的框架,Firefox 的很多功能受到了限制,然而尽管如此,Firefox 还是有着非常多的自定义空间,随着更多 API 的加入, Firefox 会在速度能比肩 Chrome 的情况下,功能也会更加强大,更加 Firefox。

    1. 要不要用 Firefox 开发者版本?
    可以用,也可以不用。开发者版的好处在于它支持直接双开Firefox,更加方便,并可直接安装未签名拓展和修改的拓展。

    2. 将官方安装版 Firefox 便捷化
    (1). 利用工具 libportable 将 Firefox 程序便携化,可以避开配置文件之间的干扰。
    (2). 下载 免沙箱Flash,让Firefox不会因为 Flash 而奔溃。

    3. 如何双开 Firefox ?
    常用的方法是:新建一个快捷方式,然后在”目标“一栏,空一格再加上 “-no-remote -p” (不包括分号)就会调出用户配置的对话框,你可以创建和删除用户配置。如果在 “-no-remote -p” 后,再空一格加上“用户配置名称”,就可以跳过选择用户配置的对话框,直接一键双开Firefox了。
    简单的方法是:我写了一个DOS批处理文件,让上述过程一键启用,点击下载

    4. 使用Firefox自带开发者工具
    按F12弹出Dev Tools,点击“齿轮”图标,在“高级设置”里勾选“启用浏览器界面和附加组件调试工具箱”和“启用远程调试器”,然后在菜单栏里的 "工具" 中“Web开发者”选择“浏览器工具箱”。

    三道杠——web开发者——查看器(Ctrl+Shift+C 或 F12)
    三道杠——web开发者——浏览器工具箱(Ctrl+Shift+Alt+I)(在RC Firefox V10中可以按 Shift+F1)

    5,如何安装未签名拓展?
    使用 Firefox 开发者版本可以直接安装,但如果使用的是正式版的话,打开 about:debugging 也可以临时安装本地扩展。

    但如果想要永久安装的话,方法一:
    (1). 用压缩软件打开 .xpi 拓展,打开找到文件 install.rdf,里面有这个拓展的ID,把它改成其他的,修改后并重新打包成 .xpi。
    (2). 在 AMO 上申请个帐号,将改好的 xpi 文件上传到 AMO Submit 上(选择”我自己托管),上传成功后下载安装即可。

    方法二:
    (1). 将正式版Firefox程序安装目录下的文件 omni.ja 用解压软件解压到 omni 文件夹,修改文件 ../modules/AppConstants.jsm。
    (2). 搜索 MOZ_REQUIRE_SIGNING,将下面的 true 修改为 false。
    (*). 如果还想安装旧式拓展的话,搜索 MOZ_ALLOW_LEGACY_EXTENSIONS,把下面的 false 改成 true。
    (3). 重新压缩整个 omni 文件夹,并将名称 omni.zip 改为 omni.ja,之后覆盖原文件。

    6,如何分享自己的配置?
    不正确的配置分享可能会导致个人私密的泄露,在分享你的配置前,你需要:
    (1),按快捷键 Shift + Ctrl + Del,删除全部浏览记录,可删除所有站点记录。
    (2),注销已登录的Firefox帐号,包括 Firefox Account,Lastpass,Pocket,Xmarks等所有同步帐号。Lastpass 还需要清除本地缓存,点击 “更多选项-->高级-->清除本地缓存”。
    (3),打开“选项-->隐私与安全”,点击 “已经已保存的登录信息”,如果有,则要删除。
    (4),删除配置文件夹下的:
    places.sqlite 书签和历史,urlclassifier3.sqlite 钓鱼网站库,cookies.sqlite 已登录网站的cookie,bookmarkbackups 自动备份的书签,OfflineCache 脱机缓存,startupCache 启动缓存,signons.sqlite 保存的密码,key3.db 密码数据库,permissions.sqlite (网站设置是,否允许cookie、安装扩展、显示图片),webappsstore.sqlite 保存的会话
    (5),根据自己配置的实际情况,其他包含个人隐私的文件和文件夹也要删除,之后就可以打包压缩上传分享了,推荐使用7Zip,压缩效率更高。

    常用工具

    Firefox开发者版 和正式版区别不大,但无需命名可以直接双开Firefox
    Line Icons V系列Firefox所用到的线性图标及源文件
    Notepad2 编码工具,还有同类软件Notepad++,Sublime Text 3
    Beyond Compare 文件对比工具
    libportable 让官方安装版Firefox变成便携版
    DB Browser for Sqlite Sqlite 查看编辑器
    Regester 正则表达测试工具

    常用代码

    Firefox Quantum 由于 API 的变化,许多脚本代码都失效了,奶酪重新修复并整理了一份兼容 Firefox Quantum (Firefox 60+) 的列表清单。测试方法是使用快捷键 Shift + F4,在弹出的代码草稿纸窗口中将选项“环境”更改为“浏览器”,再将代码粘贴到上面,点击“执行—>运行”即可(Ctrl + R)。

    一、导航命令:

    // 1,后退
    document.getElementById("Browser:Back").doCommand();
    或者 getWebNavigation().canGoBack && getWebNavigation().goBack();
    // 2,前进
    document.getElementById("Browser:Forward").doCommand();
    或者 getWebNavigation().canGoForward && getWebNavigation().goForward();
    // 3,刷新当前页面
    document.getElementById("Browser:Reload").doCommand();
    // 4,跳过缓存刷新当前页面
    document.getElementById("Browser:ReloadSkipCache").doCommand();
    // 5,刷新所有页面
    gBrowser.reloadAllTabs();
    // 6,主页
    BrowserHome(); 或者 document.getElementById("Browser:Home").doCommand();
    // 7,停止载入当前页面
    document.getElementById("Browser:Stop").doCommand();
    // 8,添加书签
    document.getElementById("Browser:AddBookmarkAs").doCommand();
    // 9,打开文件
    document.getElementById("Browser:OpenFile").doCommand();
    // 10,保存文件
    document.getElementById("Browser:SavePage").doCommand();
    // 11,打印预览
    document.getElementById("cmd_printPreview").doCommand();
    // 12,打印
    document.getElementById("cmd_print").doCommand();
    // 13,显示/隐藏书签工具栏
    var bar = document.getElementById("PersonalToolbar"); setToolbarVisibility(bar, bar.collapsed);
    // 14,显示/隐藏菜单栏
    document.getElementById("toolbar-menubar").setAttribute("autohide", document.getElementById("toolbar-menubar").getAttribute("autohide") == "true" ? "false" : "true");
    // 15,显示/隐藏导航栏
    var toolbar = document.getElementById("nav-bar"); toolbar.collapsed = !toolbar.collapsed; document.persist(toolbar.id, "collapsed");
    // 16,显示/隐藏查找栏
    if ("isFindBarVisible" in gFindBar) gFindBar.isFindBarVisible() ? gFindBar.closeFindBar() : gFindBar.onFindCmd(); else gFindBar.hidden ? gFindBar.onFindCommand() : gFindBar.close();
    或者 gFindBar.hidden ? gFindBar.onFindCommand() : gFindBar.close();
    // 17,清除搜索栏内容
    document.getElementById("searchbar").value = "";
    // 18,重启浏览器
    Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);
    // 19,关闭浏览器
    goQuitApplication();
    // 20,打开书签管理
    document.getElementById("Browser:ShowAllBookmarks").doCommand();
    // 21,打开Cookies管理
    window.open("chrome://browser/content/preferences/cookies.xul", "Browser:Cookies", "chrome,resizable=yes");
    // 22,打开密码管理
    window.open("chrome://passwordmgr/content/passwordManager.xul", "Toolkit:PasswordManager", "chrome,resizable=yes");
    // 23,打开证书管理
    window.open("chrome://pippki/content/certManager.xul", "mozilla:certmanager", "chrome,resizable=yes,all,width=600,height=400");
    // 24,打开下载窗口
    BrowserDownloadsUI();
    // 25,打开我的足迹窗口
    PlacesCommandHook.showPlacesOrganizer('History');

    二、窗口命令:

    // 1,新建窗口
    document.getElementById("cmd_newNavigator").doCommand();
    // 2,关闭窗口
    document.getElementById("cmd_closeWindow").doCommand();
    // 3,窗口最小化
    window.minimize(); 或者 minimize();
    // 4,窗口常规化和最大化间切换
    window.windowState == window.STATE_MAXIMIZED ? window.restore() : window.maximize();
    // 5,窗口全屏
    document.getElementById("View:FullScreen").doCommand();
    // 6,在小窗口打开指定页面
    格式是:toOpenWindowByType('标题', '地址);,比如 打开about:config 页面,
    toOpenWindowByType('about:config', 'about:config');
    如果要指定窗口大小,
    window.open("about:config", "about:config", "chrome,resizable=yes,centerscreen").resizeTo(800, 600);
    // 7,窗口占用屏幕左半部分
    resizeTo(screen.availWidth / 2, screen.availHeight, moveTo(0, 0));
    // 8,窗口占用屏幕右半部分
    resizeTo(screen.availWidth / 2, screen.availHeight, moveTo(screen.availWidth / 2, 0));
    // 9,显示所有标签页缩略图
    allTabs.open();

    三、标签命令:

    // 1,新建标签
    document.getElementById("cmd_newNavigatorTab").doCommand();
    或者 BrowserOpenTab();
    // 2,关闭标签
    document.getElementById("cmd_close").doCommand();
    或者 gBrowser.removeCurrentTab();
    // 3,恢复最后一次关闭的标签
    document.getElementById("History:UndoCloseTab").doCommand();
    // 4,将标签移动到左边
    var tab = gBrowser.mCurrentTab; var pos = Math.max(0, tab._tPos - 1); gBrowser.moveTabTo(tab, pos);
    // 5,将标签移动到右边
    var tab = gBrowser.mCurrentTab; var pos = Math.min(gBrowser.mTabs.length - 1, tab._tPos + 1); gBrowser.moveTabTo(tab, pos);
    // 6,激活下一个标签页
    gBrowser.tabContainer.advanceSelectedTab(-1, true);
    // 7,激活下一个标签页
    gBrowser.tabContainer.advanceSelectedTab(1, true);
    // 8,激话第一个标签页
    gBrowser.selectedTab = gBrowser.tabContainer.firstChild;
    // 9,激话最后一个标签页
    gBrowser.selectedTab = gBrowser.tabContainer.childNodes[gBrowser.tabContainer.childNodes.length-1];
    // 10,复制当前标签页
    duplicateTabIn(gBrowser.selectedTab, 'tab');
    或者 openNewTabWith(gBrowser.currentURI.spec, null, null, null, false);
    // 11,关闭左边标签页
    var tab = gBrowser.mCurrentTab.boxObject.previousSibling; if(tab) gBrowser.removeTab(tab);
    // 12,关闭右边标签页
    var tab = gBrowser.mCurrentTab.boxObject.nextSibling;if(tab) gBrowser.removeTab(tab);
    // 13,关闭左侧标签页
    for (let i = gBrowser.mCurrentTab._tPos - 1; i >= 0; i--) if (!gBrowser.tabs[i].pinned){ gBrowser.removeTab(gBrowser.tabs[i], {animate: true});}
    // 14,关闭右侧标签页
    gBrowser.removeTabsToTheEndFrom(gBrowser.mCurrentTab);
    // 15,关闭其他标签页
    gBrowser.removeAllTabsBut(gBrowser.mCurrentTab);
    // 16,关闭所有标签页
    gBrowser.removeAllTabsBut(gBrowser.mCurrentTab); gBrowser.removeCurrentTab();
    // 17,在当前标签页右边新建标签页:
    var x = gBrowser.mCurrentTab._tPos + 1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addTab("about:blank"), x);
    // 18,关闭重复标签页
    var num=gBrowser.browsers.length;var msg="";for(var i=0;i

    四、页面命令:

    // 1,向上滚动一屏
    goDoCommand("cmd_scrollPageUp");
    // 2,向下滚动一屏
    goDoCommand("cmd_scrollPageDown");
    // 3,向右滚动一屏
    goDoCommand('cmd_scrollRight');
    // 4,向左滚动一屏
    goDoCommand('cmd_scrollLeft');
    // 5,滚动至页首
    goDoCommand("cmd_scrollTop");
    // 6,滚动至页尾
    goDoCommand("cmd_scrollBottom");
    // 7,查看页面源代码
    document.getElementById("View:PageSource").doCommand();
    // 8,查看页面信息
    document.getElementById("View:PageInfo").doCommand();
    或者 BrowserPageInfo();
    // 9,上一页
    loadURI(gBrowser.currentURI.spec.replace(/(\d+)(?=\D*$)/, function($0) {return +$0 - 1 > 0 ? +$0 - 1 : 0;}));
    // 10,下一页
    loadURI(gBrowser.currentURI.spec.replace(/(\d+)(?=\D*$)/, function($0) {return +$0 + 1}));
    // 11,进入阅读模式
    var url = "about:reader?url=" + gBrowser.currentURI.spec; gBrowser.selectedTab = gBrowser.loadURI(url);
    // 12,关闭当前标签声音
    gBrowser.selectedTab.toggleMuteAudio();

    五、工具栏命令:

    // 1,打开下载界面
    document.getElementById("Tools:Downloads").doCommand();
    // 2,打开附加组件
    document.getElementById("Tools:Addons").doCommand();
    或者 BrowserOpenAddonsMgr();
    // 3,删除历史记录
    document.getElementById("Tools:Sanitize").doCommand();
    // 4,打开设置
    openPreferences();

    六、侧边栏命令:

    // 1,侧边栏打开书签栏
    SidebarUI.toggle("viewBookmarksSidebar");
    // 2,侧边栏打开历史记录
    SidebarUI.toggle("viewHistorySidebar");
    // 3,关闭侧边栏
    var sidebarBox = document.getElementById("sidebar-box"); if (!sidebarBox.hidden) toggleSidebar(sidebarBox.getAttribute("sidebarcommand"));
    // 4,侧边栏打开当前网页
    openWebPanel(document.title, gBrowser.currentURI.spec);

    七、地址栏命令:

    // 1,在当前标签打开网页
    gBrowser.loadURI('http://www.baidu.com');
    // 2,在新标签打开网页 (后台)
    gBrowser.addTab("http://www.baidu.com");
    // 3,在新标签打开网页 (前台)
    gBrowser.selectedTab = gBrowser.addTab("http://www.baidu.com");
    // 4,在当前标签右侧打开网页
    var x = gBrowser.mCurrentTab._tPos + 1; gBrowser.moveTabTo(gBrowser.selectedTab =gBrowser.addTab("about:about"), x);
    // 5,复制当前标签页标题
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); gClipboardHelper.copyString(gBrowser.contentTitle);
    // 6,复制当前标签页地址
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); gClipboardHelper.copyString(gBrowser.currentURI.spec);
    // 7,复制当前标签页标题和地址
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var txt="";var url=gBrowser.currentURI.spec;var title=gBrowser.contentTitle;txt+=title+"\n"+url+"\n";gClipboardHelper.copyString(txt);
    // 8,复制当前标签页源代码
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var txt="";var url=gBrowser.currentURI.spec;var title=gBrowser.contentTitle;txt+=""+title+""+"\r";gClipboardHelper.copyString(txt);
    // 9,复制当前标签页MD源代码
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var txt="";var url=gBrowser.currentURI.spec;var title=gBrowser.contentTitle;txt+="["+title+"]"+"("+url+")";gClipboardHelper.copyString(txt);
    // 10,复制所有标签页标题
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var titles="";Array.slice(gBrowser.tabContainer.childNodes).forEach(function(tab){titles+=tab.label+"\n"});gClipboardHelper.copyString(titles);
    // 11,复制所有标签页地址
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var URLs="";Array.slice(gBrowser.tabContainer.childNodes).forEach(function(tab){var url=gBrowser.getBrowserForTab(tab).currentURI.spec;URLs+=url+"\n"});gClipboardHelper.copyString(URLs);
    // 12,复制所有标签页标题和地址
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var txt="";Array.slice(gBrowser.tabContainer.childNodes).forEach(function(tab){var url=gBrowser.getBrowserForTab(tab).currentURI.spec;txt+=tab.label+"\n"+url+"\n"});gClipboardHelper.copyString(txt);
    // 13,复制所有标签页源代码
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var txt="";Array.slice(gBrowser.tabContainer.childNodes).forEach(function(tab){var url=gBrowser.getBrowserForTab(tab).currentURI.spec;txt+=""+tab.label+"+"\r"});gClipboardHelper.copyString(txt);
    // 14,复制所有标签页MD源代码
    var gClipboardHelper = Components.classes['@mozilla.org/widget/clipboardhelper;1'].getService(Components.interfaces.nsIClipboardHelper); var txt="";Array.slice(gBrowser.tabContainer.childNodes).forEach(function(tab){var url=gBrowser.getBrowserForTab(tab).currentURI.spec;txt+="["+title+"]"+"("+url+")\\"+"\r"});gClipboardHelper.copyString(txt);
    // 15,打开剪切板内容
    openUILinkIn(readFromClipboard(),
    gBrowser.currentURI.spec=="about:blank"&&!gBrowser.selectedTab.hasAttribute("busy")?"current":"tab",true);
    // 16,一键打开常用标签组
    var newtabs=["http://weibo.com/","https://www.inoreader.com/","https://www.twitter.com/","http://www.runningcheese.com/"];var i=0;while(i<=newtabs.length-1){gBrowser.selectedTab=gBrowser.addTab(newtabs[i]);i=i+1};

    八、其他命令:

    // 1,模拟按钮点击
    比如,模拟点击最小化按钮,双引号之间的ID内容需要在当前界面可见。(包括下拉选项)
    document.getElementById("titlebar-min").click();
    或者 document.getElementById("titlebar-min").doCommand();
    // 2,模拟键盘点击
    比如,模拟点击回车键,DOM_VK_RETURN 代表 回车键,更多虚拟键码可参考 这里
    window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).sendKeyEvent('keypress', KeyEvent.DOM_VK_RETURN, 0, 0);
    // 3,运行小书签命令
    小书签的优点在于全平台兼容,各大浏览器都能运行,命令也非常多,可参考《中文网最全小书签合集》。比如,开启夜晚模式:
    gBrowser.loadURI("javascript:(function(){var%20night=function(w){(function(d){var%20css='html{opacity:0.9!important;background:black!important;}body{background:white!important;}';var%20s=d.getElementsByTagName('style');for(var%20i=0,si;si=s[i];i++){if(si.innerHTML==css){si.parentNode.removeChild(si);return}};var%20heads=d.getElementsByTagName('head');if(heads.length){var%20node=d.createElement('style');node.type='text/css';node.appendChild(d.createTextNode(css));heads[0].appendChild(node)}})(w.document);%20for(var%20i=0,f;f=w.frames[i];i++){try{arguments.callee(f)}catch(e){}}};night(window)})();");
    // 4,运行相对路径文件 (以打开配置文件夹下的 user.js 为例)
    FileUtils.getFile('ProfD',['user.js']).launch();
    再比如打开脚本文件夹下的某个文件,代码是:(来自 File I/O
    FileUtils.getFile('UChrm',['Local', 'Colors','Colors.exe']).launch();
    // 5,运行绝对路径文件 (以打开IE为例)
    var path="C:\\Program Files\\Internet Explorer\\iexplore.exe"; var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile); file.initWithPath(path); file.launch();
    // 6,使用其他浏览器打开当前页面 (以IE浏览器为例)
    var path='C:\\Program Files\\Internet Explorer\\iexplore.exe';var file=Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsIFile);file.initWithPath(path);var process=Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);process.init(file);process.run(false,[gBrowser.currentURI.spec],1);
    // 7,运行系统文件 (以打开资源管理器为例)
    var path ="..\\..\\explorer.exe"; var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);file.initWithPath(path.replace(/^\./, Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("SysD", Components.interfaces.nsIFile).path));file.launch();
    // 8,设置指定的整数值 (以设置链接以什么样的方式打开为例)
    Services.prefs.setIntPref("browser.link.open_newwindow",3);
    // 9,设置指定的字符串 (以设置默认主题为例)
    // 字符串通常内容比较复杂,为避免不必要的错误,可以加上双引号。
    Services.prefs.setCharPref("lightweightThemes.selectedThemeID","firefox-compact-light@mozilla.org");
    // 10,设置指定的布尔值 (以设置侧边栏是否靠左为例)
    Services.prefs.setBoolPref("sidebar.position_start",true);
    // 11,布尔值切换 (以设置侧边栏靠左还是靠右为例)
    var key = "sidebar.position_start"; Services.prefs.setBoolPref(key, ! Services.prefs.getBoolPref(key));
    或者 Services.prefs.setBoolPref("sidebar.position_start", ! Services.prefs.getBoolPref("sidebar.position_start"));
    如果在切换布尔值的时候,同时显示提醒的话
    var key="sidebar.position_start";Services.prefs.setBoolPref(key,!Services.prefs.getBoolPref(key));if(getBoolPref(key)==true){alert('左侧打开侧边栏')}else{alert('右侧打开侧边栏')}
    如果想让提醒显示在状态栏的话
    var key="sidebar.position_start";Services.prefs.setBoolPref(key,!Services.prefs.getBoolPref(key));if(getBoolPref(key)==true){XULBrowserWindow.statusTextField.label="左侧打开侧边栏"}else{XULBrowserWindow.statusTextField.label="右侧打开侧边栏"}
    // 12,根据键值来做 if 判断 (以侧边栏靠左时窗口常规化为例)
    if (Services.prefs.getPrefType("sidebar.position_start") === true) {window.restore();} else {window.maximize();}
    如果是多重判断的话用 &&,比如
    (Services.prefs.getPrefType("general.useragent.override") == 0 && Services.prefs.getPrefType("general.platform.override") == 0) {window.restore();} else {window.maximize();}
    // 13,重置指定键值 (以重置侧边栏停靠位置为例)
    Services.prefs.clearUserPref("sidebar.position_start")
    // 14,命令切换启用 (以显示或者隐藏查找栏为例)
    gFindBar.open() || gFindBar.close();

    注意事项:
    (1). 以上代码如果太长不便于理解,可以借助 JS代码美化 工具来展开代码。
    (2). 当引用的代码段有双引号时,可以使用 function() { 引用的代码 }; 来转义,有多重双引号时,外面一层用单引号。
    (3). 当代码较长遇到隔断时,可以借助 JS代码净化 工具来压缩代码。
    (4). 如果还是有隔断,可以使用 URL编码工具
    (5). 你还可以通过使用”开发者工具箱“来查找更多命令,或者访问 MDN 开发者中心。

    参数设置

    Firefox 诞生于 Unix,保留有 Unix 的系统哲学,Firefox 可以通过修改参数来修改设置,方法是在地址栏打开 about:config 来手动修改,对于这些选项的修改,Firefox 会将记录保存到文件 pref.js 中去。然而,我更喜欢的是将一些常用的设置写入到文件 user.js 中去, 这样即使遇到配置出了问题, 将 prefs.js 文件删除, 重启 Firefox 后一切都又回到熟悉的样子。 在 user.js 中参数有两种写法, 一种是pref,一种是user_pref:

    pref(key,value) 会覆盖默认设置,在删除之后会恢复默认设置。
    user_pref(key,value)等同于从about:config修改,删除之后,修改的设置仍然有效。

    about:config 可以对 Firefox 的界面进行修改(参考本文“用户样式”篇),也可以对 Firefox 的功能进行修改,下面这些常见的选项是你应该知道的:

    1,控制Firefox内存使用

    // 关闭标签动画:
    toolkit.cosmeticAnimations.enabled 设置为 false。(老机器可以设置为false,高配电脑无需设置)
    // 设置标签页面缓存的数量:
    browser.sessionhistory.max_total_viewers 设置为 8。电脑内存小于4GB的,可以设置为4,默认为-1,意为无限大。
    // 设置标签前进/后退历史记录缓存:
    browser.sessionhistory.max_entries 设置为 25。默认为50。
    // 最小化时释放物理内存:
    config.trim_on_minimize,设置为 true。这个值不存在,需要手动建立新的布尔值。

    2,设置标签打开方式

    // 设置链接是否在新窗口中打开:
    browser.link.open_newwindow 设置为 3。
    默认为3,3表示在新标签页中打开,2表示在新窗口中打开,1表示在当前窗口或者标签页中打开。
    // 设置通过 JavaScript 打开的链接是否与上面的方式保持一致:
    browser.link.open_newwindow.restriction 设置为0。
    默认为0,0表示保持一致,1表示在新窗口中打开,2表示依据 JavaScript 的具体设置。

    3,更多选项设置
    Firefox 有非常多的 about:config 高级设置,目前已知对 about:config 参数进行解释的地方有:About:config entries火狐参数目录Ghack user.js。其中 Ghack user.js 最为详细具体,告诉你各个版本有什么变化、新增和删除,更新也非常及时,还提供了一些很实用的脚本操作命令(预览),https://ffprofile.com/ 是一个引导式的 user.js 生成器,还有一份奶酪在用的 user.js 供你参考。

    用户代理

    User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

    一些网站常常通过判断 UA 来给不同的操作系统、不同的浏览器发送不同的页面,因此可能造成某些页面无法在某个浏览器中正常显示,但通过伪装 UA 可以绕过检测。比如一些网站只支持Chrome,而不支持Firefox,比如斗鱼在Chrome上可以启用HTML5播放器,这时可以通过修改UA的方法解决。

    一、用 About:config 修改

    新建字符串 general.useragent.override,输入
    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36
    则会修改整个浏览器的 UA。

    新建字符串 general.useragent.override.douyu.com,输入
    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36
    则会单单修改访问 douyu.com 时的浏览器 UA,修改其他的网站和UA,方法相同。

    虎牙要使用HTML5播放器,需要额外将 javascript.options.streams 和 dom.streams.enabled 设置为 ture。

    二、用拓展修改

    当然,上面这些步骤都一些麻烦,我们可以利用拓展 Header Editor 来快速修改。还是以将国内常见直播平台伪装成Chrome浏览器HTML5播放器为例:

    注意事项:
    (1). 红色圈为必填内容,可能需要一些正则表达式的知识,但你可以按^https?://www\.douyu\.com.* 依葫芦画瓢,修改网址就可以了,多个正则之间用“|”隔开(不包括分号)表示并列。

    (2). 支持列表订阅:
    常用图片反盗链和反跳转 by dupontjoy
    常用重定向和用户代理 by runningcheese

    (3). 常见UA列表:

    // 1,iPad:
    Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25
    // 2,iPhone:
    Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16
    // 3,Opera:
    Opera/9.80 (Windows NT 6.1; U) Presto/2.6.30 Version/10.60
    // 4,Safari:
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:48.0) Gecko/20100101 Firefox/48.0
    // 5,Chrome:
    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36
    // 6,Android:
    Mozilla/5.0 (Linux; U; Android 2.0; en-us; Droid Build/ESD20) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17
    // 7,Wechat:
    Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; NX510J Build/LMY47V) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025489 Mobile Safari/533.1 V1_AND_SQ_6.2.3_336_YYB_D QQ/6.2.3.2700 NetType/WIFI WebP/0.3.0 Pixel/1080
    // 8,Google爬虫:
    Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
    // 9,Firefox 52:
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0
    // 10,Firefox 57:
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0

    (4). 当前浏览器UA查询工具:UA分析,还可以用 小书签 来查询,所有浏览器UA查询:List of User Agent Strings

    用户规则

    (批量自定义且自动更新)

    一个网页里有百度联盟的广告,我们可以通过用 hosts 的方法将百度联盟的广告指向 127.0.0.1,这样百度联盟的广告就屏蔽了。然而,这个网页同时又加入了谷歌Ads的广告,过加入了淘宝联盟的广告,这时用户规则就诞生了。

    1,广告过滤规则
    拓展推荐: uBlock Origin,AdBlock Plus 或者 YiClear,省事可以用 YiClear
    EasyList:广告过滤必须订阅的主规则。
    EasyList China:中文订阅规则,配合 EasyList 主规则使用。
    Adblock Warning Removal List:针对于那种“警告,你正在使用Adblock”的提示,可以理解为反“反ABP”。
    ABP Subscriptions :已知所有的 Adblock Plus 规则

    2,隐私保护规则
    拓展推荐:同上
    EasyPrivacy:反跟踪,隐私保护主规则。
    CJX’s Annoyance List:针对中文网站的隐私保护补充规则。

    3,用户代理规则
    拓展推荐: Header Editor
    一网站通过判断字符串头来给不同的操作系统、不同的浏览器发送不同的页面,因此可能造成某些页面无法在某个浏览器中正常显示,但通过伪装 UserAgent 用户代理来绕过检测。

    Dupontjoy Redirctor:网页重定向
    RunningCheese Redirtor:参考自Dupontjoy Redirctor,修改了部分重定向,无需重复订阅。
    Dupontjoy Referer:反反图片盗链。
    RunningCheese UserAgent:常见网站 UserAGent 修改。

    4,代理规则
    拓展推荐: Proxy SwitchyOmega
    用户代理是指用户身份的代理(UserAgnet),代理是指代理服务器(Proxy Server),就国内而言,无非就是那个“List”。

    5,其他规则
    还有一些其他类型的规则,比如通过规则批量定义网页的样式,但是样式管理器也有同样的功能,而且更加方便好用,所以这种规则不常用。还有自动翻页的规则,看个人的使用情况是否添加,还有一些是白名单规则,比如 NoScript 的白名单。

    通常情况下,订阅规则就可以满足绝大部分的情况,也可以根据自己的使用情况添加一些自定义规则。需要注意的是,应该要避免添加太多的规则列表,这会减慢浏览器的处理速度,进而影响浏览体验。

    用户样式

    (自定义浏览器外观)

    自 Firefox 更新到 Firefox Quantum 后,Firefox 有了一个全新的外观,除了 Firefox 自带的“定制”功能外,虽然现在无法通过拓展直接修改浏览器外观,但你还可以通过强大的 userChrome.css 来自定义你的浏览器外观, Firefox Quantum 仍然保有强大的自定义功能,这是其他任一一款浏览器都做不到的。

    一、什么是 userChormecss

    什么是 userChorme.css? 要理解它,首先要知道 Chrome 是什么意思,Chrome 是金属铬的意思,但在浏览器中指的是浏览器的框架,所以在 Firefox 的目录文件夹下会有 "chrome" 文件夹。谷歌公司旗下的 Chrome 浏览器的命名很讨巧,有点“面包牌面包”的意思。这里,我们延伸拓展一下,Firefox 默认有四个支持自定义功能的文件,它们都位于配置文件夹下的 “chrome” 文件夹里,总的说来就是:Chrome 代表 Firefox 的界面,Content 代表网页内容,分别是:

    userChrome.css -浏览器界面的样式表 (无管理拓展)
    userContent.css -网页的样式表 (管理拓展:比如 xStyle)
    userChrome.js -浏览器界面的脚本 (无管理拓展)
    userContent.js -网页的脚本 (管理拓展:比如 ViolentMonkey)



    比如,通过 userChrome.css 修改浏览器界面字体的大小:
    window { font-size: 5mm !important; font-family: helvetica !important;}

    比如,通过 userContent.css 修改网页字体的大小:
    html>body { font-size: 100% !important; line-height: normal !important;}

    二、如何编写用户样式

    userChrome.css 位于浏览器配置文件夹下的“chrome”文件夹下,如果没有,你则需要手动新建。每次启动 Firefox,Firefox 都会加载这个样式表应用到全局浏览器中去,Firefox 57+ 版本以后,无法通过拓展直接修改,只能在 userChrome.css 上修改。如果CSS代码过长,可以使用 @import url("xxxx.css"); 来导入。需要注意的几个方面:

    (1). 当你的CSS代码只是是做用于浏览器界面时,可以在代码放到下面的规则里,以避免与网页的样式表冲突。
    @-moz-document url(chrome://browser/content/browser.xul) {/* 你的CSS代码 */}

    (2). 需要在CSS样式表前声明 /* AGENT_SHEET */ 吗?
    一般来说,userChrome.css 会覆盖Firefox的内置的样式表,特别是你使用了 !important 声明代码,但是还是有一些本地匿名元素,比如滚动栏,会不起作用,这时你就需要在样式表前加入 /* AGENT_SHEET */

    (3). 在 userChrome.css 的同一文件夹内还会有一个叫 userContent.css 的文件,这个是将样式应用到网页上的,但使用 xStyle 等样式管理拓展更加方便,所以这个文件不常用。但是对于一些 Firefox 浏览器的内建页,比如 about:addons, about:preferences, about:newtab,样式管理拓展是不起作用的,这时就要用到 userContent.css 了,比如:
    @-moz-document url(about:preferences),url-prefix(about:preferences) {/* 你的CSS代码 */}

    (4). 如何即见即所得的编辑CSS样式表,避免每次修改后都要重启,就像旧版 Stylish 那样?
    使用浏览器自带的“开发者工具”可以做到即见即所到,点击“保存”按钮可以将当前修改直接保存到样式表中去。
    DOM

    (5). 启用开发者工具需要按F12在设置中勾选两个选项,查找浏览器元素时,使用"DOM"更加方便准确,DOM标签默认并未勾选,查找弹出式菜单需要点击“弹窗自动隐藏”选项,更多使用方法可以参考 MDN
    DOM

    (6). 最常用的选择器 ID, class, name,他们之间的区别就是ID是你的身份证号码,class是你的姓别和民族,name就是你的名字,如果使用label选择器的话,需要用中括号括起来,像[label="XXXX"]这样。

    (7). 要想知道当前选中的选择器是不是你想要的,可以给它定义一下属性,比如 color:#0063dc !important; 或者 display:none !important; 这样就很明显了,加 !important 是为了让这个属性值具有优先权。

    (8). 在修改其他人的CSS样式表时,要想快速地知道某个属性具体是那条代码影响的,可以在100行代码中选择第50-100行,删除应用后,看看效果还在不在,如果还在,那么继续删除第25-50行的代码,直到效果消失后就可以缩小查找范围了。

    (9). CSS编辑工具可以选项V系列Firefox自带的 Notepad2,也可以使用 Notepad++,还可以使用更加美观的 Atom。

    (10). 一些选择符 是Firefox 特有的,只在Firefox上有效。比如以-moz-开头的,比如以两个横线"--sidebar-hover-width"开头的,详细列表查看:https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions

    三、案例:如何修改按钮图标?

    以修改拓展 In My Pocket 图标为例,使用“开发者工具箱”选择 Pocket 图标,得到其ID为“_cd7e22de-2e34-40f0-aeff-cec824cbccac_-browser-action”,那CSS写法就是:

    #_cd7e22de-2e34-40f0-aeff-cec824cbccac_-browser-action {
    list-style-image: url("../images/pocket.png") !important;
    }

    双引号中间的指定图像可以是像上面代码所示的图片相对路径地址,也可以是以http://开头的绝对路径地址,也可以是以 data:image/png;base64 开头的图片base64编码。

    四、通过“定制”和"about:config"来修改浏览器界面

    Firefox 上的一些界面改变是可以通过“定制”和"about:config"来修改的,比如下载按钮是否自动隐藏,标签栏上方是否有拖拽空间,这里有一份中文解释说明可供参考:

    1,通过“定制”

    // 1,工具栏模式:
    定制模式 > 密度 > (紧凑 / 普通 / 触控)
    // 2,标签栏上方拖拽空间:
    定制模式 > 拖拽空间 > 勾选选择
    // 3,下载按钮一直可见:
    定制模式 > 下载按钮 > 点击按钮取消勾选“自动隐藏”
    // 4,RSS 图标放入地址栏:
    可以安装拓展 Awesome RSS

    2,通过”about:config“
    地址栏输入 about:config,搜索相应的参数修改,布尔值为是和否,整数值为数值,字符串为字母和数字。右键点击选择“重置”可以恢复到默认数值。

    // 1,标签栏最小宽度:(建议为100)
    browser.tabs.tabMinWidth
    //2,是否在标签上显示音频播放按钮:(建议选是)
    browser.tabs.showAudioPlayingIcon
    // 3,在当前标签右边插入相关标签:(建议选是)
    browser.tabs.insertRelatedAfterCurrent
    // 4,是否隐藏地址栏前的 http:// 标识:(建议选否)
    browser.urlbar.trimURLs
    // 5,新标签打开限制: (建议为0,用新标签来代替新窗口)
    browser.link.open_newwindow.restriction
    // 6,是否使用 Tabs 键来预览标签:(建议选否)
    browser.ctrlTab.previews
    // 7,关闭最后一个标签时关闭浏览器:(建议选否)
    browser.tabs.closeWindowWithLastTab
    // 8,使用旧版拨号页和主页界面:(建议选否)
    browser.newtabpage.activity-stream.enabled
    browser.newtabpage.activity-stream.aboutHome.enabled
    // 9,HTML5 全屏警告:(修改时间,-1为不显示)
    full-screen-api.warning.delay
    full-screen-api.warning.timeout
    // 10,书签栏显示最近添加的书签:(建议选否)
    browser.bookmarks.showRecentlyBookmarked
    // 11,是否显示标签动画:(建议选否)
    toolkit.cosmeticAnimations.enabled
    // 12,HTML5 全屏淡进和淡出动画时间:(修改时间,-1为不显示)
    full-screen-api.transition-duration.enter
    full-screen-api.transition-duration.leave
    // 13,是否在附加组件页面移除“获取拓展”选项:(建议选否)
    extensions.getAddons.showPane
    // 14,搜索栏结果动画变暗高亮:(建议选否)
    findbar.modalHighlight
    // 15,是否在地址栏底部添加搜索引擎切换的按钮:(建议选否)
    browser.urlbar.oneOffSearches
    // 16,是否启用阅读模式按钮:
    reader.parse-on-load.enabled
    // 17,是否启用地理位置定位:(根据个人情况选择)
    geo.enabled
    // 18,是否启用Pocket按钮:(建议选否,功能很弱)
    extensions.pocket.enabled
    // 19,是否启用截图按钮:(建议选是,不错,支持永久图床)
    extensions.screenshots.disabled
    // 20,是否启用容器标签页:(建议选是,不错,也就是小号功能)
    privacy.userContext.enabled
    // 21,是否启用物联网扩展:(建议选否)
    dom.flyweb.enabled
    // 22,字体渲染:(默认即可,如果要使用MacType,要修改为 direct2d1.1,cairo,skia)
    gfx.canvas.azure.backends
    gfx.content.azure.backends

    五、用户样式资源列表

    开发资源

    Mozilla MDN Mozilla 开发者网络
    MDN Addons 开始编写你的第一个浏览器扩展
    Mozilla Knowledge Base Mozilla 知识库
    MozillaWiki Mozilla 产品开发指南
    Mozilla Central Source Mozilla 源码索引
    Bugzilla Main Page 火狐 Bug 反馈中心
    Demos MDN MDN 开发网络技术演示
    About:config entries about:config 说明
    火狐参数目录 about:config 说明中文版
    Ca-archive 传统拓展档案,下载已经被AMO移除了的传统拓展
    Are We XBL Still? 新版Firefox API变化
    火狐中文教程 非常详细,by @江3
    Firefox Webext List 非常详细,WE拓展替代传统拓展进度表
    DXR 源代码库
    MozillaWiki Mozilla 项目Wiki文档
    Web 技术文档 Firefox 开发所需语言技术
    正则表达式 正则表达式入门教程

    UC脚本

    新架构的 Firefox Quantum 最大的变化就是抛弃了原有的XUL语言界面,这使得以 .uc.xul 为后缀名的UC脚本完全失效,同时因为一些API的变化,也使得一部分以 .uc.js 为后缀名的UC脚失效。但总的来说,Firefox 官方对UC脚本的态度是开放的,UC脚本依然大有可为,因为UC脚本真的实在太好用了。

    1. UC脚本到底是什么东西?
    UC脚本的全称是 userchrome.js,从本质上来说,它和一般的 javascript 脚本一样,都是js语言,只不过它引用了 Firefox 专有的库,只能在 Firefox 上运行。

    2. 让 Firefox Quantum 支持 UC脚本
    使用的是 Endor8 的方案,通过配置脚本来完成userChrome的配置,共计4个文件。
    ..\Firefox\defaults\pref\config-prefs.js
    ..\Firefox\defaults\pref\channel-prefs.js
    ..\Firefox\config.js
    ..\Firefox\userChromeJS.js

    3. 有哪些保持着更新的UC脚本开发者?
    alice0775/userChrome.js
    Endor8/userChrome.js
    ardiman/userChrome.js
    userChrome.js用スクリプト
    harv/userChromeJS
    scdhao/userChrome
    胖子阿康/userChrome
    RunningCheese/userChrome.js

    一些已经停止更新的UC脚本开发者名单就没有列出来了,同样十分感谢脚本原开发者。
    可能用得上的参考资料:ywzhaiqi/userChromeJSdefpt/userChromeJs
    更多UC脚本,可搜索 Search · userChrome

    拓展和脚本

    (Firefox有什么可以折腾的?)

    1、拓展 Extensions

    拓展是一种具有一些新功能的加载项,在 Firefox拓展中心 上有着丰富的优秀拓展,相信Firefox拓展强大的功能会让你再也离不开Firefox,你可以根据个人需求来安装适合个人需求的拓展。

    2、插件 Plugins

    初学者最容易把拓展和插件混淆了,通俗的讲,扩展是基于Firefox本身增加的一些实用功能,而插件则是在Firefox之外独立编写的程序,用于显示网页中的特定内容,比如Flash,上传插件,网银插件和Java等。

    3、用户样式 Userstyles

    我们可以利用它来定制目标网页或网站的css样式,甚至一些Firefox 拓展的样式,让浏览效果更加舒适。而且在 UserStyles 网站上已经有不少现成的样式可供下载,让不会写css的普通用户也可以享受到它的便利。

    4、用户脚本 Userscripts

    能通过脚本来改变被访问网页,能使你访问的网站更便于阅读或者更便于使用。在 GreasyFork 上有许多用户分享的用户脚本,打开脚本的安装页面,点击 “Install” 按钮就可以完成安装了。

    5、UC脚本 UserchromeJS

    区别于用户脚本,UC脚本可以针对于火狐浏览器进行定制来实现效果,而用户脚本的功能只能针对网页页面,UC脚本可以代替某些用户脚本和某些拓展,而UC脚本的优势在于它是轻量级的。在 Github 上有许多开发者发布的UC脚本。

    PS: 看了上面这些术语名词,你可能还会想另外一个词 (附加组件Addons),它并不特指某一个东西,而是以上术语名词的统称。

    官方网站

    桌面版下载:Firefox 官方FTP下载Firefox 国际多语言下载火狐中文(谋智)版Firefox 每夜体验版
    移动版下载:Firefox iOS版Firefox 安卓版附加组件下载:Firefox Addons

    Mozilla Firefox Firefox 官方网站
    火狐浏览器 Firefox 中文官方网站
    The Mozilla Blog Mozilla 官方博客
    Mozilla Blog Directory Mozilla 博客目录
    Mozilla Add-ons Blog Mozilla 附加组件博客
    Mozilla Future Releases Mozilla 发展方向博客
    Mozilla Security Blog Mozilla 安全博客
    Open Policy & Advocacy Mozilla 隐私保护博客
    Mozilla Hacks Web开发技巧与资讯
    Mozilla Community Mozilla 社区
    Planet Mozilla Mozilla 社区人员博客汇总

    新闻资讯

    Firefox News Firefox 新闻 (英文)
    Firefox News Firefox 新闻 (中文)
    Firefox Facebook Firefox Facebook 社交网络
    Firefox Twitter Firefox Twitter 社交网络
    火狐的微博 Firefox 微博社交网络
    Firefox Release Notes Mozilla 更新日志
    Firefox Archives Firefox 资讯技巧
    Solidot Firefox Solidot Firefox资讯
    Solidot Mozilla Solidot Mozilla资讯
    Techdows Firefox Techdows Firefox资讯
    浏览器国内市场份额 StatCounter Global Stats 浏览器全球市场份额
    Firefox 信仰充值中心 Firefox 知乎专栏

    论坛社区

    Mozilla Discourse Mozilla官方交流论坛
    谋智火狐社区 Mozilla火狐中文官方论坛
    MozillaZine Forums 全球最大用户交流论坛
    Stackoverflow Firefox 英文问答
    Reddit Firefox 英文版Firefox贴吧
    Mozilla Firefox中文社区 最忠实
    Mozilla Mozest 最可惜
    卡饭论坛Firefox版 最技术
    Firefox贴吧 最活跃
    Mozilla 台灣社群 宝岛朋友
    知乎 Firefox话题 知乎 Firefox话题
    简书 Firefox专题 简书 Firefox专题
    V2EX Firefox V2EX Firefox话题
    Camp Firefox 德国 Firefox 论坛
    Mozilla Support Moziila 技术支持论坛
    Pale Moon forum Pale Moon forum

    博客项目

    个人博客:
    Mike's Musings Mozilla元老级员工博客
    pcxFirefox 编译版Firefox
    奔跑中的奶酪 定制版
    Kaiyuan Liu GM脚本
    CingFox 定制版
    阳光盒子 定制版
    火狐范 资讯
    反斗软件 资讯
    wiki@nothing UC脚本(日文)


  • 结尾


    只写了一部分,后续将继续更新,欢迎自荐、推荐与Firefox相关的优秀资源网站和开发者。Just You Know Why~
二维码

扫描本页面二维码
用手机浏览本站

QR:Firefox 火狐不完全开发手册

Top