├── README.md ├── Reference.md ├── mynewtabmod@sakuyaa ├── bootstrap.js ├── chrome.manifest ├── chrome │ ├── content │ │ ├── calendar.min.js │ │ ├── img │ │ │ ├── add.png │ │ │ ├── change.png │ │ │ ├── logo.png │ │ │ └── setting.png │ │ ├── index.html │ │ └── index.js │ ├── locale │ │ ├── en-US │ │ │ ├── global.properties │ │ │ └── options.dtd │ │ ├── zh-CN │ │ │ ├── global.properties │ │ │ └── options.dtd │ │ └── zh-TW │ │ │ ├── global.properties │ │ │ └── options.dtd │ └── skin │ │ ├── sakuyaa.png │ │ ├── style.css │ │ └── weather.css ├── install.rdf ├── myNewTabMod │ ├── data.txt │ └── ico │ │ ├── baidu.svg │ │ ├── github.svg │ │ └── kafan.ico └── options.xul ├── pic ├── bingImg.png ├── config.png ├── default.png ├── main.png └── prefs.png ├── update └── mynewtabmod@sakuyaa.rdf └── xpi ├── mynewtabmod-1.0-fx.xpi ├── mynewtabmod-1.1-fx.xpi ├── mynewtabmod-1.2-fx.xpi ├── mynewtabmod-1.3-fx.xpi ├── mynewtabmod-1.4-fx.xpi ├── mynewtabmod-1.4.1-fx.xpi ├── mynewtabmod-1.5-fx.xpi ├── mynewtabmod-1.6-fx.xpi ├── mynewtabmod-1.6.1-fx.xpi ├── mynewtabmod-1.6.2-fx.xpi ├── mynewtabmod-1.7-fx.xpi ├── mynewtabmod-1.7.1-fx.xpi ├── mynewtabmod-1.7.2-fx.xpi ├── mynewtabmod-1.7.3-fx.xpi ├── mynewtabmod-1.8-fx.xpi ├── mynewtabmod-1.8.1-fx.xpi ├── mynewtabmod-1.8.2-fx.xpi ├── mynewtabmod-2.0-fx.xpi ├── mynewtabmod-2.0.1-fx.xpi └── mynewtabmod-lastest.xpi /README.md: -------------------------------------------------------------------------------- 1 | # myNewTabMod by sakuyaa 2 | 3 | 该扩展的WebExtension版本[myNewTabWE](https://github.com/sakuyaa/myNewTabWE)正在开发中。由于API的限制,部分功能无法实现,新的扩展需要重新进行配置。 4 | 5 | 首先感谢一下原作者`defpt`和`ywzhaiqi`:clap:, 6 | 这个扩展是根据[myNewTab](http://bbs.kafan.cn/thread-1759418-1-1.html)这个扩展修改而成的 7 | 8 | ## 主要的不同之处 9 | 1. 实现火狐41上设置为新标签页 10 | * 将参数存放在火狐preferences里面 11 | * 将导航配置、壁纸等可能有改动的文件设置在profile文件夹内,实现扩展签名 12 | * 扩展重装后不会覆盖配置 13 | * 替换日历算法为我自己编写的算法,从而准确显示父亲节:man:、母亲节:woman:这样的节日 14 | * 可在扩展数据文件夹内自定义网页css 15 | * 神秘的代码:underage: 16 | 17 | ## 可能造成不便的地方 18 | 1. 存放导航网址的数据文件data.txt中,为网址指定本地图标文件时需要以斜杠`/`开头 19 | * 我写的农历算法由于是使用公式自动计算的缘故,可能会出现一些错误(已修复2010-2020年存在的误差) 20 | * Bing壁纸的命名还是采取日期+壁纸的信息,不会自动删除,需要注意壁纸会一直累积下去 21 | * 默认的导航网址中有返利链接 22 | * 在火狐配置文件目录里的扩展数据文件夹中的自定义css文件并不会随着扩展目录的chrome\skin文件夹的默认css文件更新 23 | * 扩展数据文件夹中自定义style.css文件优先级高于默认css文件,weather.css文件将直接覆盖默认css文件 24 | 25 | ## 扩展图文 26 | * 扩展主界面,左上角的天气可以在附加组件管理器中该扩展选项界面设置其URL 27 | 国历和农历日期会以不同颜色显示当天的节假日和节气信息 28 | ![](https://raw.githubusercontent.com/sakuyaa/myNewTabMod/master/pic/main.png "主界面") 29 | * 参数设置 30 | ![](https://raw.githubusercontent.com/sakuyaa/myNewTabMod/master/pic/config.png "参数设置") 31 | * 将参数存放在火狐preferences里面 32 | ![](https://raw.githubusercontent.com/sakuyaa/myNewTabMod/master/pic/prefs.png "首选项") 33 | * 储存的Bing壁纸 34 | ![](https://raw.githubusercontent.com/sakuyaa/myNewTabMod/master/pic/bingImg.png "Bing图片") 35 | 36 | ## 尚未解决(能力有限…) 37 | * ~~由于使用了css3 transform移动来使主界面居中(这样才能保证每行的宽度不超过最大宽度时,导航宽度会自动适应),导致导航右边框消失。同时,当拖动导航网址时,链接并不会出现在鼠标上,而是鼠标右侧~~ 已使用marginLeft替代transform使界面居中 38 | * chrome页面似乎用不了localStorage? 39 | * 加载天气网页缓慢时会影响主页面的加载 40 | -------------------------------------------------------------------------------- /Reference.md: -------------------------------------------------------------------------------- 1 | # myNewTabMod Reference by sakuyaa 2 | 3 | 这是我在开发过程中所参考的一些资料:smirk: 4 | 5 | ## [Add-ons](https://developer.mozilla.org/docs/Mozilla/Add-ons) 6 | 1. **Version** 7 | * [Version Format](https://developer.mozilla.org/en-US/docs/Toolkit_version_format) 8 | * [Extension Versioning, Update and Compatibility](https://developer.mozilla.org/docs/Extension_Versioning%2C_Update_and_Compatibility) 9 | * **Preferences** 10 | * [Preferences](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Preferences) 11 | * [内嵌选项](https://developer.mozilla.org/docs/Mozilla/Add-ons/Inline_Options) 12 | * [setting.xml](https://dxr.mozilla.org/mozilla-central/source/toolkit/mozapps/extensions/content/setting.xml) 13 | * **L10n** 14 | * [本地化](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/Tutorial/Localization) 15 | * [Localizing an extension](https://developer.mozilla.org/docs/Mozilla/Localization/Localizing_an_extension) 16 | * [Property Files](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/Tutorial/Property_Files) 17 | * [demo](https://github.com/Noitidart/l10n) 18 | * **Others** 19 | * [设置扩展开发环境](https://developer.mozilla.org/docs/Mozilla/Add-ons/Setting_up_extension_development_environment) 20 | * [自引导型扩展](https://developer.mozilla.org/docs/Mozilla/Add-ons/Bootstrapped_extensions) 21 | * [File I/O](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O) 22 | * [Custom about: URLs](https://developer.mozilla.org/docs/Custom_about:_URLs) 23 | * [e10s chrome脚本](https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Limitations_of_chrome_scripts#nsIAboutModule) 24 | * [browser.js](https://dxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js) 25 | 26 | ## [JavaScript code modules](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Using) 27 | 1. **[Downloads.jsm](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Downloads.jsm)** 28 | * **[OSFile.jsm](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/OSFile.jsm)** 29 | * [OS.File for the main thread](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File_for_the_main_thread) 30 | * [Calling OS.File.DirectoryIterator from the main thread](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File.DirectoryIterator_for_the_main_thread) 31 | * [Path manipulation](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.Path) 32 | * [OS.File.DirectoryIterator.Entry](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File.DirectoryIterator.Entry) 33 | * **PlacesUtils.jsm** 34 | * favicons 35 | * [mozIAsyncFavicons](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/mozIAsyncFavicons) 36 | * [nsIFaviconDataCallback](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFaviconDataCallback) 37 | * **[Services.jsm](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Services.jsm)** 38 | * appinfo 39 | * [nsIXULAppInfo](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXULAppInfo) 40 | * [nsIXULRuntime](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXULRuntime) 41 | * io 42 | * [nsIIOService](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIIOService) 43 | * prefs 44 | * [nsIPrefBranch](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrefBranch) 45 | * [nsIPrefService](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrefService) 46 | * prompt 47 | * [nsIPromptService](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService) 48 | * strings 49 | * [nsIStringBundleService](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIStringBundleService) 50 | * vc 51 | * [nsIVersionComparator](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIVersionComparator) 52 | * wm 53 | * [nsIWindowMediator](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowMediator) 54 | * **[XPCOMUtils.jsm](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm)** 55 | 56 | ## [XPCOM Interface](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface) 57 | * [nsIAboutModule](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAboutModule) 58 | * [nsIAlertsService](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAlertsService) 59 | * [nsIDOMWindowUtils](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindowUtils) 60 | * [nsIFile](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile) 61 | * [nsIFilePicker](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker) 62 | * [nsILocalFile](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile) 63 | * [nsIObserver](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIObserver) 64 | * [nsIProcess](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess) 65 | * [nsIStringBundle](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIStringBundle) 66 | 67 | ## [XUL](https://developer.mozilla.org/docs/Mozilla/Tech/XUL) 68 | * [browser](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/browser) 69 | * [tab](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/tab) 70 | * [tabbrowse](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/tabbrowser) 71 | 72 | ## [JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Reference) 73 | 1. **[全局对象](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects)** 74 | * [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error) 75 | * [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise) 76 | * [正则表达式](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RegExp) 77 | * **[语句](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements)** 78 | * [for...in](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...in) 79 | * [for...of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of) 80 | * **[运算符](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators)** 81 | * [解构赋值](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) 82 | * **[函数](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions)** 83 | * [arguments](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/arguments) 84 | * [箭头函数](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) 85 | * **附加参考** 86 | * [严格模式](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Strict_mode) 87 | 88 | ## [Web API 接口](https://developer.mozilla.org/docs/Web/API) 89 | * [Notification](https://developer.mozilla.org/docs/Web/API/notification) 90 | * [TextDecoder](https://developer.mozilla.org/docs/Web/API/TextDecoder) 91 | * [XMLHttpRequest](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest) 92 | -------------------------------------------------------------------------------- /mynewtabmod@sakuyaa/bootstrap.js: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * myNewTabMod by sakuyaa. 3 | * 4 | * https://github.com/sakuyaa/ 5 | **************************************************/ 6 | 'use strict'; 7 | 8 | const {classes: Cc, interfaces: Ci, manager: Cm, utils: Cu/*, results: Cr*/} = Components; 9 | Cu.import('resource://gre/modules/osfile.jsm'); 10 | Cu.import('resource://gre/modules/Services.jsm'); 11 | Cu.import('resource://gre/modules/XPCOMUtils.jsm'); 12 | 13 | //版本判断 14 | const is41Up = Services.vc.compare(Services.appinfo.platformVersion, '41') >= 0; 15 | const is44Up = Services.vc.compare(Services.appinfo.platformVersion, '44') >= 0; 16 | const is48Up = Services.vc.compare(Services.appinfo.platformVersion, '48') >= 0; 17 | if (is41Up && !is44Up) { 18 | Cu.import('resource:///modules/NewTabURL.jsm'); //火狐41上使用新标签页API 19 | } 20 | 21 | var myNewTabMod = { 22 | stringBundle: Services.strings.createBundle('chrome://mynewtabmod/locale/global.properties'), //本地化 23 | prefs: Services.prefs.getDefaultBranch('extensions.myNewTabMod.'), 24 | PREFS: { 25 | setHomePage: true, //设置为主页 26 | setNewTab: true, //设置为新标签页 27 | backgroundImage: '', //背景图片地址 28 | bingMaxHistory: 10, //最大历史天数,可设置[2, 16] 29 | imageDir: 'bingImg', //图片存储的文件夹名字 30 | isNewTab: true, //是否新标签页打开导航链接或搜索结果 31 | path: 'myNewTabMod', //myNewTabMod文件夹的相对于配置文件的路径 32 | reuseNewTab: true, //重用新标签页 33 | title: '我的主页', //网页标题 34 | useBigImage: true, //bing图片的尺寸,0为默认的1366x768,1为1920x1080 35 | useBingImage: true, //使用bing的背景图片 36 | weatherSrc: 'http://i.tianqi.com/index.php?c=code&id=8&num=3' //天气代码的URL 37 | }, 38 | 39 | log: function(e) { 40 | if (e.lineNumber) { 41 | console.log('myNewTabMod bootstrap line#' + e.lineNumber + ': ' + e); 42 | } else { 43 | console.log('myNewTabMod bootstrap: ' + e); 44 | } 45 | }, 46 | addPrefs: function() { 47 | try { 48 | this.PREFS.title = this.stringBundle.GetStringFromName('prefs.title'); 49 | } catch(e) { 50 | this.log(e); 51 | } 52 | for (var [key, value] in Iterator(this.PREFS)) { 53 | try { 54 | switch (typeof value) { 55 | case 'string': 56 | var str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString); 57 | str.data = value; 58 | this.prefs.setComplexValue(key, Ci.nsISupportsString, str); 59 | break; 60 | case 'number': 61 | this.prefs.setIntPref(key, value); 62 | break; 63 | case 'boolean': 64 | this.prefs.setBoolPref(key, value); 65 | break; 66 | } 67 | } catch(e) { 68 | this.log(e); 69 | } 70 | } 71 | }, 72 | copyFile: function(oldFilePath, path, newFilePath) { 73 | var oldFile = OS.Path.join(OS.Constants.Path.profileDir, 'extensions', 'mynewtabmod@sakuyaa', 'myNewTabMod', oldFilePath); 74 | if (newFilePath) { 75 | try { 76 | OS.File.copy(oldFile, OS.Path.join(OS.Constants.Path.profileDir, path, newFilePath), {noOverwrite: true}); 77 | } catch(e) { 78 | this.log(e); 79 | } 80 | } else { //文件夹复制操作 81 | var newFileFolder = OS.Path.join(OS.Constants.Path.profileDir, path, oldFilePath); 82 | try { 83 | OS.File.makeDir(newFileFolder); 84 | } catch(e) { 85 | this.log(e); 86 | } 87 | let iterator = new OS.File.DirectoryIterator(oldFile); 88 | iterator.forEach(entry => { 89 | try { 90 | OS.File.copy(entry.path, OS.Path.join(newFileFolder, OS.Path.basename(entry.path)), {noOverwrite: true}); 91 | } catch(e) { 92 | this.log(e); 93 | } 94 | }).then(() => { 95 | iterator.close(); 96 | }, reason => { 97 | iterator.close(); 98 | this.log(reason); 99 | }); 100 | } 101 | }, 102 | 103 | //设置主页和新标签页 104 | setHomePage: function(reset) { 105 | //reset为undefined,随setHomePage参数改变而设置;reset为true或false时,仅当setHomePage参数为true时设置 106 | var url = this.prefs.prefHasUserValue('setHomePage') ? null : 'about:mynewtabmod'; 107 | if (url && !reset) { 108 | Services.prefs.setCharPref('browser.startup.homepage', url); 109 | } else if (url && reset || !url && reset == undefined) { 110 | Services.prefs.clearUserPref('browser.startup.homepage'); 111 | } 112 | }, 113 | setNewTab: function(reset) { 114 | var url = this.prefs.prefHasUserValue('setNewTab') ? null : 'about:mynewtabmod'; 115 | if (url && !reset) { 116 | if (is44Up) { 117 | Cc['@mozilla.org/browser/aboutnewtab-service;1'].getService(Ci.nsIAboutNewTabService).newTabURL = url; 118 | } else { 119 | is41Up ? NewTabURL.override(url) : Services.prefs.setCharPref('browser.newtab.url', url); 120 | } 121 | } else if (url && reset || !url && reset == undefined) { 122 | if (is44Up) { 123 | Cc['@mozilla.org/browser/aboutnewtab-service;1'].getService(Ci.nsIAboutNewTabService).resetNewTabURL(); 124 | } else { 125 | is41Up ? NewTabURL.reset() : Services.prefs.clearUserPref('browser.newtab.url'); 126 | } 127 | } 128 | }, 129 | 130 | //参数的改变 131 | register: function() { 132 | this.prefs.addObserver('', this, false); 133 | }, 134 | unregister: function() { 135 | this.prefs.removeObserver('', this); 136 | }, 137 | observe: function(aSubject, aTopic, aData) { 138 | if (aTopic == 'nsPref:changed') { 139 | switch (aData) { 140 | case 'setHomePage': 141 | this.setHomePage(); 142 | break; 143 | case 'setNewTab': 144 | this.setNewTab(); 145 | break; 146 | } 147 | } 148 | } 149 | }; 150 | 151 | function AboutModule() {} 152 | AboutModule.prototype = Object.freeze({ 153 | page: 'chrome://mynewtabmod/content/index.html', 154 | classDescription: 'about:mynewtabmod about page', 155 | contractID: '@mozilla.org/network/protocol/about;1?what=mynewtabmod', 156 | classID: Components.ID('d2d4f4d6-389f-4bb2-9905-c6ae30c84a58'), //https://www.famkruithof.net/uuid/uuidgen 157 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), 158 | 159 | getURIFlags: function(aURI) { 160 | return Ci.nsIAboutModule.ALLOW_SCRIPT; 161 | }, 162 | newChannel: function(aURI) { 163 | var channel; 164 | if (is48Up) { 165 | channel = Services.io.newChannel2(this.page, null, null, null, 166 | Services.scriptSecurityManager.getSystemPrincipal(), null, 167 | Ci.nsILoadInfo.SEC_NORMAL, Ci.nsIContentPolicy.TYPE_OTHER); 168 | } else { 169 | channel = Services.io.newChannel(this.page, null, null); //Obsolete since Gecko 48 170 | } 171 | channel.originalURI = aURI; 172 | return channel; 173 | } 174 | }); 175 | Cm.QueryInterface(Ci.nsIComponentRegistrar); 176 | function Factory(component) { 177 | this.createInstance = function(outer, iid) { 178 | if (outer) { 179 | throw Cr.NS_ERROR_NO_AGGREGATION; 180 | } 181 | return new component(); 182 | }; 183 | this.register = function() { 184 | Cm.registerFactory(component.prototype.classID, component.prototype.classDescription, component.prototype.contractID, this); 185 | }; 186 | this.unregister = function() { 187 | Cm.unregisterFactory(component.prototype.classID, this); 188 | }; 189 | Object.freeze(this); 190 | this.register(); 191 | } 192 | var factory; 193 | 194 | /*bootstrap entry points*/ 195 | var startup = function(data, reason) { 196 | try { 197 | factory = new Factory(AboutModule); 198 | } catch(e) { 199 | myNewTabMod.log(e); 200 | } 201 | myNewTabMod.addPrefs(); 202 | myNewTabMod.register(); 203 | myNewTabMod.setNewTab(false); 204 | switch (reason) { 205 | case ADDON_INSTALL: 206 | case ADDON_UPGRADE: 207 | case ADDON_DOWNGRADE: 208 | //以下代码不写在install里,是因为install调用在Registering manifest之前,无法使用stringBundle 209 | var path; 210 | try { 211 | path = Services.prefs.getComplexValue('extensions.myNewTabMod.path', Ci.nsISupportsString).toString(); 212 | } catch(e) { 213 | path = 'myNewTabMod'; 214 | } 215 | if (path != 'myNewTabMod') { 216 | try { 217 | if (Services.prompt.confirm(null, myNewTabMod.stringBundle.GetStringFromName('title.folder'), 218 | myNewTabMod.stringBundle.formatStringFromName('alert.folder', [path], 1)) == false) { 219 | path = 'myNewTabMod'; 220 | } 221 | } catch(e) { 222 | myNewTabMod.log(e); 223 | } finally { 224 | Services.prefs.setCharPref('extensions.myNewTabMod.path', path); 225 | } 226 | } 227 | //将文件复制到目录外,以避免文件修改之后导致扩展签名失败 228 | try { 229 | OS.File.makeDir(OS.Path.join(OS.Constants.Path.profileDir, path)); 230 | } catch(e) { 231 | myNewTabMod.log(e); 232 | } 233 | myNewTabMod.copyFile('ico', path, false); 234 | myNewTabMod.copyFile('data.txt', path, 'data.txt'); 235 | //myNewTabMod.copyFile('style.css', path, 'style.css'); 236 | 237 | //判断完path的路径后再检查style.css文件是否存在,若存在且需更新时提示 238 | if (reason == ADDON_UPGRADE) { 239 | OS.File.exists(OS.Path.join(OS.Constants.Path.profileDir, path, 'style.css')).then(aExists => { 240 | if (aExists && Services.vc.compare(data.oldVersion, '1.8') < 0) { 241 | Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService).showAlertNotification('chrome://mynewtabmod/skin/sakuyaa.png', 'myNewTabMod', myNewTabMod.stringBundle.GetStringFromName('notify.upgrade')); 242 | } 243 | }).catch(myNewTabMod.log); 244 | } 245 | //故意不break 246 | case ADDON_ENABLE: 247 | myNewTabMod.setHomePage(false); 248 | } 249 | }; 250 | var shutdown = function(data, reason) { 251 | switch (reason) { 252 | case ADDON_DISABLE: 253 | case ADDON_UNINSTALL: 254 | //https://bugzilla.mozilla.org/show_bug.cgi?id=620541 255 | myNewTabMod.setHomePage(true); 256 | myNewTabMod.setNewTab(true); 257 | //故意不break 258 | case ADDON_UPGRADE: 259 | case ADDON_DOWNGRADE : 260 | try { 261 | factory.unregister(); 262 | } catch(e) { 263 | myNewTabMod.log(e); 264 | } 265 | myNewTabMod.unregister(); 266 | break; 267 | } 268 | }; 269 | var install = function(data, reason) { 270 | }; 271 | var uninstall = function(data, reason) { 272 | switch (reason) { 273 | case ADDON_UNINSTALL: 274 | var path; 275 | try { 276 | path = Services.prefs.getComplexValue('extensions.myNewTabMod.path', Ci.nsISupportsString).toString(); 277 | } catch(e) { 278 | path = 'myNewTabMod'; 279 | } 280 | try { 281 | if (Services.prompt.confirm(null, myNewTabMod.stringBundle.GetStringFromName('title.delete'), 282 | myNewTabMod.stringBundle.formatStringFromName('alert.delete', [path], 1))) { 283 | OS.File.removeDir(OS.Path.join(OS.Constants.Path.profileDir, path)).catch(e => { 284 | myNewTabMod.log(e); 285 | }); 286 | } 287 | } catch(e) { 288 | myNewTabMod.log(e); 289 | } 290 | myNewTabMod.prefs.deleteBranch(''); //升降级不删除参数 291 | //故意不break,使得扩展移除并安装后能刷新stringBundle 292 | case ADDON_UPGRADE: 293 | case ADDON_DOWNGRADE: 294 | //https://bugzilla.mozilla.org/show_bug.cgi?id=719376 295 | Services.strings.flushBundles(); 296 | break; 297 | } 298 | }; 299 | -------------------------------------------------------------------------------- /mynewtabmod@sakuyaa/chrome.manifest: -------------------------------------------------------------------------------- 1 | content mynewtabmod chrome/content/ 2 | locale mynewtabmod en-US chrome/locale/en-US/ 3 | locale mynewtabmod zh-CN chrome/locale/zh-CN/ 4 | locale mynewtabmod zh-TW chrome/locale/zh-TW/ 5 | skin mynewtabmod classic/1.0 chrome/skin/ 6 | -------------------------------------------------------------------------------- /mynewtabmod@sakuyaa/chrome/content/calendar.min.js: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * Copyright © 2011-2015 sakuyaa. 3 | * All rights reserved. 4 | * 5 | * The original code was Solar.java and Lunar.java 6 | * in a java calendar project, which was created 7 | * by sakuyaa in 2011. And convert to javascript 8 | * in 2015. 9 | * 10 | * https://github.com/sakuyaa/ 11 | **************************************************/ 12 | var Solar={a:new Array('星期日','星期一','星期二','星期三','星期四','星期五','星期六'),b:new Array('0101*元旦','0214情人节','0308妇女节','0312植树节','0315消费者权益日','0401愚人节','0501*劳动节','0504青年节','0512护士节','0601儿童节','0701建党节','0801建军节','0910教师节','1001*国庆节','1031万圣节前夜','1101万圣节','1111光棍节','1224平安夜','1225圣诞节'),c:new Array('0520母亲节','0630父亲节','1144感恩节'),d:function(a){return a%400==0||(a%4==0&&a%100!=0)},e:function(a){var c=0;for(var b=1900;b0&&c.getDate()-b*7<=0){return this.c[d].substring(4)}}}return''},getSolar:function(a){var b={date:(a.getMonth()+1)+' 月'+a.getDate()+' 日 '+this.a[a.getDay()],festival:'',holiday:''};var c=this.f(a);if(c.charAt(0)=='*'){b.holiday=c.substring(1)}else{b.festival=c}return b}};var Lunar={a:new Array('小寒','大寒','立春','雨水','惊蛰','春分','清明','谷雨','立夏','小满','芒种','夏至','小暑','大暑','立秋','处暑','白露','秋分','寒露','霜降','立冬','小雪','大雪','冬至'),b:'甲乙丙丁戊己庚辛壬癸',c:'子丑寅卯辰巳午未申酉戌亥',d:'鼠牛虎兔龙蛇马羊猴鸡狗猪',e:new Array('闰','正月','二月','三月','四月','五月','六月','七月','八月','九月','十月','冬月','腊月'),f:'初一二三四五六七八九十廿',g:new Array('0101*春节','0115元宵','0202龙抬头','0303上巳节','0505*端午','0707七夕','0715中元节','0815*中秋','0909重阳','1001寒衣节','1015下元节','1208腊八节','1224小年','1230除夕'),h:1900,i:0,j:new Array(),k:1,l:1,m:true,x:{1382:-1,1393:-1,1395:-1,1408:-1,1413:1,1418:-1,1426:1,1430:-1,1483:-1,1489:1,1493:-1},y:{201111:1,201212:1,201416:1,201511:1,201615:1,201702:-1,201816:1},n:function(a){if(a in this.x){return Math.floor(1.6+29.5306*a+0.4*Math.sin(1-0.45058*a))+this.x[a]}return Math.floor(1.6+29.5306*a+0.4*Math.sin(1-0.45058*a))},o:function(b,a){if((b*100+a) in this.y){return Math.floor(365.242*(b-1900)+6.2+15.22*a-1.9*Math.sin(0.262*a))+this.y[b*100+a]}return Math.floor(365.242*(b-1900)+6.2+15.22*a-1.9*Math.sin(0.262*a))},p:function(c){for(;this.ha){break}}if(this.n(this.i+12)<=this.o(this.h,23)){for(var b=0;b<12;b++){a=this.o(this.h,2*b+1);if(this.n(this.i+b)>a||this.n(this.i+b+1)<=a){this.j.push(this.i+b);break}}}}},q:function(c){this.m=false;this.p(c.getFullYear());var b=Solar.e(c);var a=(c.getFullYear()-1900)*12-1;for(;;a++){if(this.n(a)<=b&&this.n(a+1)>b){var e=this.j.length;for(var d=0;da){e=d;break}}this.k=(a-e+11)%12+1;this.l=b-this.n(a)+1;break}}},r:function(b){var c=b.getFullYear();var a=Solar.e(b);if(aa){return this.b[c%10]+this.c[c%12]+'月 '}}},t:function(b){var a=Solar.e(b);a+=9;for(;a<0;){a+=60000}return this.b[a%10]+this.c[a%12]+'日 '},u:function(b){this.q(b);var a=this.e[this.k];if(this.l<=10){a+=this.f[0]+this.f[this.l]}else{if(this.l>10&&this.l<20){a+=this.f[10]+this.f[this.l%10]}else{if(this.l==20){a+=this.f[2]+this.f[10]}else{if(this.l==30){a+=this.f[3]+this.f[10]}else{a+=this.f[11]+this.f[this.l%10]}}}}return this.m?this.e[0]+a:a},v:function(b){var a=Solar.e(b);for(var c=0;c<24;c++){if(a==this.o(b.getFullYear(),c)){return this.a[c]}}return''},w:function(){for(var a=0;a 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 |