diff --git a/common.js b/common.js index 01f7a7c..ed82a94 100644 --- a/common.js +++ b/common.js @@ -9,7 +9,73 @@ var ua = { vendor: '' }; -var onBeforeSendHeaders = ({requestHeaders}) => { +var prefs = { + ua: '', + blacklist: [], + whitelist: [], + mode: 'blacklist' +}; + +chrome.storage.local.get(prefs, ps => { + Object.assign(prefs, ps); + update(prefs.ua); +}); +chrome.storage.onChanged.addListener(ps => { + Object.keys(ps).forEach(key => prefs[key] = ps[key].newValue); + if (ps.ua) { + update(prefs.ua); + } +}); + +function hostname(url) { + const s = url.indexOf('//') + 2; + if (s > 1) { + let o = url.indexOf('/', s); + if (o > 0) { + return url.substring(s, o); + } + else { + o = url.indexOf('?', s); + if (o > 0) { + return url.substring(s, o); + } + else { + return url.substring(s); + } + } + } + else { + return url; + } +} +function match(url) { + if (prefs.mode === 'blacklist') { + if (prefs.blacklist.length) { + const h = hostname(url); + return prefs.blacklist.some(s => s === h); + } + } + else { + if (prefs.blacklist.length) { + const h = hostname(url); + return prefs.whitelist.some(s => s === h) === false; + } + else { + return true; + } + } +} + +var cache = {}; +chrome.tabs.onRemoved.addListener(id => delete cache[id]); + +var onBeforeSendHeaders = ({tabId, url, requestHeaders, type}) => { + if (type === 'main_frame') { + cache[tabId] = match(url); + } + if (cache[tabId]) { + return; + } for (let i = 0, name = requestHeaders[0].name; i < requestHeaders.length; i += 1, name = requestHeaders[i].name) { if (name === 'User-Agent' || name === 'user-agent') { requestHeaders[i].value = ua.userAgent; @@ -22,6 +88,9 @@ var onBeforeSendHeaders = ({requestHeaders}) => { var onCommitted = ({frameId, url, tabId}) => { if (frameId === 0 && url && (url.startsWith('http') || url.startsWith('ftp'))) { + if (cache[tabId]) { + return; + } chrome.tabs.executeScript(tabId, { runAt: 'document_start', allFrames: true, @@ -73,11 +142,6 @@ User-Agent String: ${str || navigator.userAgent}` }); } -chrome.storage.local.get({ - ua: '' -}, prefs => update(prefs.ua)); -chrome.storage.onChanged.addListener(prefs => prefs.ua && update(prefs.ua.newValue)); - // FAQs & Feedback chrome.storage.local.get({ 'version': null, @@ -86,10 +150,12 @@ chrome.storage.local.get({ const version = chrome.runtime.getManifest().version; if (prefs.version ? (prefs.faqs && prefs.version !== version) : true) { + const p = Boolean(prefs.version); chrome.storage.local.set({version}, () => { chrome.tabs.create({ url: 'http://add0n.com/useragent-switcher.html?version=' + version + - '&type=' + (prefs.version ? ('upgrade&p=' + prefs.version) : 'install') + '&type=' + (p ? ('upgrade&p=' + prefs.version) : 'install'), + active: p === false }); }); } diff --git a/data/options/index.html b/data/options/index.html new file mode 100644 index 0000000..502ff2a --- /dev/null +++ b/data/options/index.html @@ -0,0 +1,37 @@ + + + + My Test Extension Options + + + + + + + + + + + + + + + + + +
+ +
+ +
+

+ + +

+ + + + diff --git a/data/options/index.js b/data/options/index.js new file mode 100644 index 0000000..b07e1cf --- /dev/null +++ b/data/options/index.js @@ -0,0 +1,36 @@ +'use strict'; +function prepare(str) { + return str.split(/\s*,\s*/) + .map(s => s.replace('http://', '') + .replace('https://', '').split('/')[0].trim()) + .filter((h, i, l) => h && l.indexOf(h) === i); +} + +function save() { + chrome.storage.local.set({ + blacklist: prepare(document.getElementById('blacklist').value), + whitelist: prepare(document.getElementById('whitelist').value), + mode: document.getElementById('mode-blacklist').checked ? 'blacklist' : 'whitelist' + }, () => { + restore(); + // Update status to let user know options were saved. + const status = document.getElementById('status'); + status.textContent = 'Options saved.'; + setTimeout(() => status.textContent = '', 750); + }); +} + +function restore() { + chrome.storage.local.get({ + mode: 'blacklist', + whitelist: [], + blacklist: [] + }, prefs => { + document.getElementById('mode-blacklist').checked = prefs.mode === 'blacklist'; + document.getElementById('mode-whitelist').checked = prefs.mode === 'whitelist'; + document.getElementById('blacklist').value = prefs.blacklist.join(', '); + document.getElementById('whitelist').value = prefs.whitelist.join(', '); + }); +} +document.addEventListener('DOMContentLoaded', restore); +document.getElementById('save').addEventListener('click', save); diff --git a/data/popup/index.css b/data/popup/index.css index b2c1648..bb1cc6b 100644 --- a/data/popup/index.css +++ b/data/popup/index.css @@ -110,3 +110,10 @@ input[type=button]:disabled { padding: 10px 0; white-space: nowrap; } + +#info { + padding: 0 5px; +} +#info:empty { + display: none; +} diff --git a/data/popup/index.html b/data/popup/index.html index f1d3dbe..d70c898 100644 --- a/data/popup/index.html +++ b/data/popup/index.html @@ -152,6 +152,7 @@
User-Agent String:  +
diff --git a/data/popup/index.js b/data/popup/index.js index ef1653c..f83c613 100644 --- a/data/popup/index.js +++ b/data/popup/index.js @@ -142,13 +142,26 @@ window.addEventListener('load', () => { }, 100); }); +function msg(msg) { + const info = document.getElementById('info'); + info.textContent = msg; + window.setTimeout(() => info.textContent = '', 750); +} + // commands document.addEventListener('click', ({target}) => { const cmd = target.dataset.cmd; if (cmd) { if (cmd === 'apply') { + const value = document.getElementById('ua').value; + if (value === navigator.userAgent) { + msg('Default user-agent'); + } + else { + msg('user-agent is set'); + } chrome.storage.local.set({ - ua: document.getElementById('ua').value + ua: value === navigator.userAgent ? '' : value }); } else if (cmd === 'reset') { @@ -159,6 +172,7 @@ document.addEventListener('click', ({target}) => { chrome.storage.local.set({ ua: '' }); + msg('reset to default'); } else if (cmd === 'refresh') { chrome.tabs.query({ diff --git a/manifest.json b/manifest.json index d5bc4c1..4298757 100755 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "User-Agent Switcher", - "version": "0.1.2", + "version": "0.1.3", "description": "Spoofs User-Agent strings of your browser", @@ -38,7 +38,11 @@ "default_popup": "data/popup/index.html" }, "homepage_url": "http://add0n.com/useragent-switcher.html", - "applications": { + "options_ui": { + "page": "data/options/index.html", + "chrome_style": true + }, + "applications": { "gecko": { "id": "{a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7}", "strict_min_version": "52.0"