...
 
Commits (16)
......@@ -9,4 +9,4 @@ allows the user to choose a certain page in a new tab.
### System Requirements (current version)
Firefox 45.0+
### Download
**[Download New Tab Override 3.0](https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/)**
**[Download New Tab Override 3.1](https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/)**
......@@ -4,7 +4,6 @@
<meta charset='utf-8' />
<title data-l10n-id='settings_title'></title>
<link rel='stylesheet' href='../css/settings.css' />
<link rel='shortcut icon' href='../images/icon-32.png' />
</head>
<body>
<header>
......@@ -32,7 +31,7 @@
<span class='description'>
<em data-l10n-id='url_description'></em>
</span>
<input type='text' name='url' id='url' data-l10n-id='settings_url_field' />
<input type='text' name='url' id='url' data-l10n-id='settings_url_field.placeholder' />
</div>
</form>
</div>
......
const elType = document.querySelector('#type');
const elUrl = document.querySelector('#url');
// set favicon
self.port.on('data-url', function(baseurl) {
const link = document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = baseurl + 'images/icon-32.png';
document.getElementsByTagName('head')[0].appendChild(link);
});
// translate HTML elements
self.port.on('i18n', function (t) {
const items = document.querySelectorAll('[data-l10n-id]');
for (let item of items) {
if (item.dataset.l10nId.endsWith('.placeholder')) {
item.setAttribute('placeholder', t[item.dataset.l10nId]);
} else {
item.textContent = t[item.dataset.l10nId];
}
}
});
// show preferences
self.port.on('show-preferences', (preferences) => {
elType.querySelector('[value="' + preferences.prefs['type'] + '"]').selected = true;
elUrl.value = preferences.prefs['url'];
});
// listen to preference changes
elType.addEventListener('change', function () {
self.port.emit('change-preference', { key : 'type', value : this.value });
});
......
const ONE_SECOND_IN_MILLISECONDS = 1000;
const ABOUT_UUID = '{73e40ef0-7f3c-11e6-bdf4-0800200c9a66}';
const ABOUT_PAGE = 'newtaboverride';
const ABOUT_URI = 'about:' + ABOUT_PAGE;
const CLIPBOARD_INTERVAL_IN_MILLISECONDS = 500;
const URL_CHARS_LIMIT = 2000;
const _ = require('sdk/l10n').get;
const { ActionButton } = require('sdk/ui/button/action');
const { Ci, Cm, Cr, components } = require('chrome');
const { PrefsTarget } = require('sdk/preferences/event-target');
const { setInterval, clearInterval } = require('sdk/timers');
const clipboard = require('sdk/clipboard');
const data = require('sdk/self').data;
const newTabUrlJsm = require('resource:///modules/NewTabURL.jsm').NewTabURL;
const pageMod = require('sdk/page-mod');
const preferencesService = require('sdk/preferences/service');
const prefsTarget = PrefsTarget({ branchName: 'browser.startup.'});
const self = require('sdk/self');
const services = require('resource://gre/modules/Services.jsm').Services;
const simplePrefs = require('sdk/simple-prefs');
const tabs = require('sdk/tabs');
const XPCOMUtils = require('resource://gre/modules/XPCOMUtils.jsm').XPCOMUtils;
const windows = require('sdk/windows');
const AboutPageFactory = {
createInstance: function(outer, iid) {
if (outer) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return AboutPage.QueryInterface(iid);
}
};
const AboutPage = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
getURIFlags: function(aURI) {
return Ci.nsIAboutModule.ALLOW_SCRIPT;
},
newChannel: function(aURI, aSecurity_or_aLoadInfo) {
let channel;
// Firefox >= 48
if (services.vc.compare(services.appinfo.version, '47.*') > 0) {
const uri = services.io.newURI(self.data.url('html/settings.html'), null, null);
channel = services.io.newChannelFromURIWithLoadInfo(uri, aSecurity_or_aLoadInfo);
}
// Firefox <= 47
else {
channel = services.io.newChannel(self.data.url('html/settings.html'), null, null);
}
channel.originalURI = aURI;
return channel;
}
};
const newtaboverride = {
actionButton : null,
......@@ -19,13 +62,56 @@ const newtaboverride = {
timer : false,
init : function () {
newtaboverride.initPageMod();
newtaboverride.onPrefChange();
newtaboverride.createButton();
},
initPageMod : function () {
pageMod.PageMod({
include: [ABOUT_URI],
contentScriptFile: [self.data.url('js/content-script.js')],
contentStyleFile: [self.data.url('css/settings.css')],
onAttach: function(worker) {
const t = {};
const langvars = [
'settings_ask_questions',
'settings_code_caption',
'settings_code_link',
'settings_donate',
'settings_donation_text',
'settings_licence_link',
'settings_main_caption',
'settings_support_caption',
'settings_title',
'settings_url_field.placeholder',
'type_options.about_newtab',
'type_options.clipboard',
'type_options.custom_url',
'type_options.homepage',
'type_title',
'url_description',
'url_title'
];
for (let langvar of langvars) {
t[langvar] = _(langvar);
}
worker.port.emit('data-url', self.data.url());
worker.port.emit('i18n', t);
worker.port.emit('show-preferences', simplePrefs);
worker.port.on('change-preference', (preference) => {
simplePrefs.prefs[preference.key] = preference.value;
});
}
});
},
onPrefChange : function () {
var type = simplePrefs.prefs['type'];
var newTabUrl;
const type = simplePrefs.prefs['type'];
let newTabUrl;
switch (type) {
case 'about:blank':
......@@ -37,10 +123,10 @@ const newtaboverride = {
case 'clipboard':
newTabUrl = 'about:blank';
// unfortunately there is no "clipboard changed" event…
newtaboverride.timer = setInterval(newtaboverride.clipboardAction, ONE_SECOND_IN_MILLISECONDS / 2);
newtaboverride.timer = setInterval(newtaboverride.clipboardAction, CLIPBOARD_INTERVAL_IN_MILLISECONDS);
break;
case 'custom_url':
var url = simplePrefs.prefs['url'];
const url = simplePrefs.prefs['url'];
if (url === '') {
newTabUrl = 'about:blank';
} else {
......@@ -60,13 +146,6 @@ const newtaboverride = {
}
newTabUrlJsm.override(newTabUrl);
for (let tab of tabs) {
if (tab.url === data.url('html/settings.html')) {
newtaboverride.syncPreferencesForOptionsUi(tab);
return;
}
}
},
createButton : function () {
......@@ -74,37 +153,35 @@ const newtaboverride = {
id : 'newtaboverride-button',
label : _('settings_title_short'),
icon : {
'18' : data.url('images/icon-18.png'),
'32' : data.url('images/icon-32.png'),
'36' : data.url('images/icon-36.png'),
'64' : data.url('images/icon-64.png')
'18' : self.data.url('images/icon-18.png'),
'32' : self.data.url('images/icon-32.png'),
'36' : self.data.url('images/icon-36.png'),
'64' : self.data.url('images/icon-64.png')
},
onClick : () => {
if (newtaboverride.actionButton.badge) {
newtaboverride.actionButton.badge = null;
}
for (let tab of tabs) {
if (tab.url === data.url('html/settings.html')) {
tab.activate();
return;
for (let window of windows.browserWindows) {
for (let tab of window.tabs) {
if (tab.url === ABOUT_URI) {
window.activate();
tab.activate();
return;
}
}
}
tabs.open({
url : 'html/settings.html',
onReady : (tab) => {
newtaboverride.syncPreferencesForOptionsUi(tab).port.on('change-preference', (preference) => {
simplePrefs.prefs[preference.key] = preference.value;
});
}
url : ABOUT_URI
});
}
});
},
clipboardAction : function () {
var clipboardContent = clipboard.get();
const clipboardContent = clipboard.get();
if (clipboard.currentFlavors.indexOf('text') === -1) {
return;
......@@ -124,24 +201,21 @@ const newtaboverride = {
* @see http://stackoverflow.com/a/9284473
*/
isValidUri : function (string) {
var website = /^(?:(?:https?):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
var aboutpage = /^about:(about|accounts|addons|blank|buildconfig|cache|checkerboard|config|crashes|credits|debugging|downloads|healthreport|home|license|logo|memory|mozilla|networking|newtab|performance|plugins|preferences|privatebrowsing|profiles|rights|robots|searchreset|serviceworkers|support|sync-log|sync-tabs|telemetry|webrtc)?$/i;
return website.test(string) || aboutpage.test(string);
},
syncPreferencesForOptionsUi : function (tab) {
const worker = tab.attach({
contentScriptFile : data.url('js/settings.js')
});
worker.port.emit('show-preferences', simplePrefs);
const website = /^(?:(?:https?):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
const aboutpage = /^about:(about|accounts|addons|blank|buildconfig|cache|checkerboard|config|crashes|credits|debugging|downloads|healthreport|home|license|logo|memory|mozilla|networking|newtab|performance|plugins|preferences|privatebrowsing|profiles|rights|robots|searchreset|serviceworkers|support|sync-log|sync-tabs|telemetry|webrtc)?$/i;
return worker;
return website.test(string) || aboutpage.test(string) || string === ABOUT_URI;
}
};
const main = (options) => {
Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(
components.ID(ABOUT_UUID),
ABOUT_URI,
'@mozilla.org/network/protocol/about;1?what=' + ABOUT_PAGE,
AboutPageFactory
);
newtaboverride.init();
simplePrefs.on('', newtaboverride.onPrefChange);
......@@ -158,6 +232,10 @@ const unload = (reason) => {
newtaboverride.lastClipboardUrl = false;
newTabUrlJsm.reset();
}
Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(
components.ID(ABOUT_UUID), AboutPageFactory
);
};
exports.main = main;
......
......@@ -7,7 +7,7 @@ settings_licence_link = MIT-Lizenz
settings_donation_text = Bitte erwäge eine Spende, um die weitere Entwicklung dieses Add-ons zu gewährleisten.
settings_donate = Spenden
settings_main_caption = Einstellungen
settings_support_caption = Unterstützen
settings_support_caption = Unterstützung
settings_title = Neuer Tab — Einstellungen
settings_title_short = Tab-Einst.
settings_url_field.placeholder = URL
......
......@@ -4,12 +4,12 @@ settings_ask_questions = Do you have questions? Do not hesitate to ask!
settings_code_caption = Source Code & Licence
settings_code_link = Source Code
settings_licence_link = MIT Licence
settings_donation_text = Please consider a donation to support the ongoing development of this add-on.
settings_donate = Donate
settings_main_caption = Settings
settings_support_caption = Support
settings_title = New Tab — Settings
settings_title_short = Tab Settings
settings_donation_text = Overweeg een donatie om de actieve ontwikkeling van deze add-on te steunen.
settings_donate = Doneren
settings_main_caption = Instellingen
settings_support_caption = Ondersteuning
settings_title = Nieuw tabblad – Instellingen
settings_title_short = Tabblad Instellingen
settings_url_field.placeholder = URL
type_options.about_newtab = about:newtab (Standaard)
type_options.clipboard = van klembord
......
......@@ -2,10 +2,15 @@
"id": "newtaboverride@agenedia.com",
"title": "New Tab Override (browser.newtab.url replacement)",
"name": "newtaboverride",
"version": "3.0",
"version": "3.1",
"description": "This add-on brings back the ability to change the page which is shown when opening a new tab.",
"main": "index.js",
"author": "Sören Hentzschel (agenedia.com)",
"author": {
"name": "Sören Hentzschel",
"email": "kontakt@agenedia.com",
"url": "https://agenedia.com"
},
"homepage": "https://www.soeren-hentzschel.at",
"translators": [
"Tonnes (NL)"
],
......@@ -61,6 +66,7 @@
"value": "about:newtab"
}
],
"preferencesURL": "about:newtaboverride",
"locales": {
"de": {
"description": "Dieses Add-on bringt die Funktion zurück, die Seite festzulegen, welche beim Öffnen eines neuen Tabs angezeigt wird."
......