diff --git a/extension/common.js b/extension/common.js
index 383426d..38cd2f0 100644
--- a/extension/common.js
+++ b/extension/common.js
@@ -22,6 +22,10 @@ const prefs = {
blacklist: [],
whitelist: [],
custom: {},
+ siblings: {
+ 'www.google.com': 0,
+ 'www.youtube.com': 0
+ }, // a list of domains that are considered siblings (use same index for all)
mode: 'blacklist',
color: '#777',
cache: true,
@@ -34,7 +38,7 @@ window.prefs = prefs; // access from popup
const log = (...args) => prefs.log && console.log(...args);
-// exand comma-separated keys of prefs.custom
+// expand comma-separated keys of prefs.custom and add missing keys
const expand = () => {
log('expanding custom rules');
expand.rules = {};
@@ -42,6 +46,25 @@ const expand = () => {
for (const k of key.split(/\s*,\s*/)) {
if (k) {
expand.rules[k] = prefs.custom[key];
+ // make sure all siblings have the same expanded rule
+ const i = prefs.siblings[key];
+ if (i !== undefined) {
+ for (const [hostname, j] of Object.entries(prefs.siblings)) {
+ if (i === j) {
+ expand.rules[hostname] = expand.rules[hostname] || prefs.custom[key];
+ if (expand.rules._) {
+ const x = expand.rules._.indexOf(key);
+ const y = expand.rules._.indexOf(hostname);
+ if (x !== -1 && y === -1) {
+ expand.rules._.push(hostname);
+ }
+ if (x === -1 && y !== -1) {
+ expand.rules._.push(key);
+ }
+ }
+ }
+ }
+ }
}
}
}
@@ -373,7 +396,20 @@ function match({url, tabId, cookieStoreId = DCSI}) {
return s.endsWith('.' + h) || h.endsWith('.' + s) || s.endsWith('.' + hh) || hh.endsWith('.' + s);
}
}).shift();
- let s = expand.rules[key] || expand.rules['*'];
+ let s;
+ // try to use an already resolved sibling hostname
+ const i = prefs.siblings[key];
+ if (i !== undefined) {
+ for (const [hostname, j] of Object.entries(prefs.siblings)) {
+ if (j === i && expand.rules[hostname] && typeof expand.rules[hostname] === 'string') {
+ s = expand.rules[hostname];
+ }
+ }
+ }
+ s = s || expand.rules[key];
+ // use '*' when the hostname specific key is not found
+ s = s || expand.rules['*'];
+ console.log(s);
// if s is an array select a random string
if (Array.isArray(s)) {
s = s[Math.floor(Math.random() * s.length)];
@@ -418,7 +454,7 @@ const onBeforeSendHeaders = d => {
}
const o = (cache[tabId] || ua.object(tabId, undefined, cookieStoreId));
const str = o ? o.userAgent : '';
- if (str) {
+ if (str && requestHeaders.length) {
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 = str === 'empty' ? '' : str;
diff --git a/extension/data/options/index.css b/extension/data/options/index.css
index 898deb0..f4d56ce 100644
--- a/extension/data/options/index.css
+++ b/extension/data/options/index.css
@@ -52,6 +52,7 @@ textarea {
.mode-2 {
grid-template-columns: min-content min-content;
}
+#toggle-sibling-desc,
#toggle-parser-desc,
#toggle-protected-desc,
#toggle-custom-desc,
diff --git a/extension/data/options/index.html b/extension/data/options/index.html
index 7940724..436290f 100644
--- a/extension/data/options/index.html
+++ b/extension/data/options/index.html
@@ -29,7 +29,7 @@
Description
Try to resolve the user-agent string from a JSON object; otherwise either use the default user-agent string or use the one that the user is set from the popup interface. Use "*" as the hostname to match all domains. You can randomly select from multiple user-agent strings by providing an array instead of a fixed string. If there is a "_" key in your JSON object which refers to an array of hostnames, then the extension only randomly selects the user-agent string once for each hostname inside this list. This is useful if you don't want the random user-agent to change until this browser session is over. Press here to insert a sample JSON object.
-
+
@@ -56,6 +56,13 @@
A JSON object to bypass the internal user-agent string parsing method. The keys are the actual user-agent strings and the value of each key is an object of the keys that need to be set for the "navigator" object. You can use the "[delete]" keyword if you want a key in the "navigator" object to get deleted. Press here to insert a sample JSON object.
+
+
Sibling Hostnames
+ Description
+
+
A JSON array that contains one or more groups of hostnames to have a single user-agent string per group for the "Custom Mode". For all hostnames in one group, the user-agent string calculation only occurs once, and all the other members use the same calculated string. This is useful to make sure a group of connected websites only access to the same user-agent string. Press here to insert a sample JSON array.