upgraded 1000 bots to manifest v3, added visual element to when the extension is turned on
This commit is contained in:
		@@ -18,62 +18,259 @@
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
'use strict';
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
var browser = browser || chrome
 | 
			
		||||
var user_agent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
 | 
			
		||||
// Use chrome or browser depending on the environment
 | 
			
		||||
var browser = chrome || browser;
 | 
			
		||||
 | 
			
		||||
// Custom user-agent to spoof Googlebot
 | 
			
		||||
var user_agent =
 | 
			
		||||
	"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
 | 
			
		||||
var target_urls = "*://*/*";
 | 
			
		||||
var status = 0;
 | 
			
		||||
 | 
			
		||||
// Duration to display the injected HTML (in milliseconds)
 | 
			
		||||
const DISPLAY_DURATION = 8000; // Set to 8 seconds
 | 
			
		||||
 | 
			
		||||
// Initialize storage for duration
 | 
			
		||||
browser.storage.local
 | 
			
		||||
	.set({ duration: DISPLAY_DURATION })
 | 
			
		||||
	.then(() => {
 | 
			
		||||
		console.log("Duration set to:", DISPLAY_DURATION);
 | 
			
		||||
	})
 | 
			
		||||
	.catch((error) => {
 | 
			
		||||
		console.error("Error setting duration:", error);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
// Set extension status to ON
 | 
			
		||||
function set_extension_status_ON() {
 | 
			
		||||
    status = 1;
 | 
			
		||||
    //console.log('Setting status to ON');
 | 
			
		||||
    browser.browserAction.setIcon({path: 'icon_ON_48.png'});
 | 
			
		||||
    browser.browserAction.setTitle({title: "1000 Bots"});
 | 
			
		||||
	browser.storage.local
 | 
			
		||||
		.set({ status: 1 })
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			console.log("Extension status set to ON");
 | 
			
		||||
			return browser.action.setIcon({ path: "icon_ON_48.png" });
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			return browser.action.setTitle({ title: "1000 Bots" });
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Start user-agent spoofing
 | 
			
		||||
			return startUserAgentSpoofing();
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Refresh all tabs after starting user-agent spoofing
 | 
			
		||||
			return refreshAllTabs();
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Inject the content script into all active tabs after refreshing
 | 
			
		||||
			return injectContentScript();
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error setting extension status ON:", error);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set extension status to OFF
 | 
			
		||||
function set_extension_status_OFF() {
 | 
			
		||||
    status = 0;
 | 
			
		||||
    //console.log('Setting status to OFF');
 | 
			
		||||
    browser.browserAction.setIcon({path: 'icon_OFF_48.png'});
 | 
			
		||||
    browser.browserAction.setTitle({title: "1000 Bots activate"});
 | 
			
		||||
	browser.storage.local
 | 
			
		||||
		.set({ status: 0 })
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			console.log("Extension status set to OFF");
 | 
			
		||||
			return browser.action.setIcon({ path: "icon_OFF_48.png" });
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			return browser.action.setTitle({ title: "1000 Bots activate" });
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Remove the content from all active tabs
 | 
			
		||||
			return removeInjectedContent();
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Stop user-agent spoofing
 | 
			
		||||
			return stopUserAgentSpoofing();
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Refresh all tabs before stopping the extension
 | 
			
		||||
			return refreshAllTabs();
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error setting extension status OFF:", error);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function update_icon(){
 | 
			
		||||
    if(status == 0) {
 | 
			
		||||
        set_extension_status_ON();
 | 
			
		||||
    }else{
 | 
			
		||||
        set_extension_status_OFF();
 | 
			
		||||
    }
 | 
			
		||||
// Toggle the icon between ON and OFF
 | 
			
		||||
function update_icon() {
 | 
			
		||||
	browser.storage.local
 | 
			
		||||
		.get("status")
 | 
			
		||||
		.then((result) => {
 | 
			
		||||
			if (result.status === 0) {
 | 
			
		||||
				set_extension_status_ON();
 | 
			
		||||
			} else {
 | 
			
		||||
				set_extension_status_OFF();
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error fetching extension status:", error);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start user-agent spoofing
 | 
			
		||||
function startUserAgentSpoofing() {
 | 
			
		||||
	const rules = [
 | 
			
		||||
		{
 | 
			
		||||
			id: 1,
 | 
			
		||||
			priority: 1,
 | 
			
		||||
			action: {
 | 
			
		||||
				type: "modifyHeaders",
 | 
			
		||||
				requestHeaders: [
 | 
			
		||||
					{
 | 
			
		||||
						operation: "set",
 | 
			
		||||
						header: "User-Agent",
 | 
			
		||||
						value: user_agent,
 | 
			
		||||
					},
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
			condition: {
 | 
			
		||||
				urlFilter: target_urls,
 | 
			
		||||
				resourceTypes: ["main_frame"],
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
function rewrite_user_agent_header(e){
 | 
			
		||||
    
 | 
			
		||||
    //console.log('Browser http request!');
 | 
			
		||||
 | 
			
		||||
    if(status == 0) {
 | 
			
		||||
        // console.log('Nothing to do');
 | 
			
		||||
        return {requestHeaders: e.requestHeaders};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (var header of e.requestHeaders) {
 | 
			
		||||
        if (header.name.toLowerCase() === "user-agent") {
 | 
			
		||||
            header.value = user_agent;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    //console.log('Set user-agent header to: ' + user_agent);
 | 
			
		||||
    return {requestHeaders: e.requestHeaders};
 | 
			
		||||
 | 
			
		||||
	// Add the rules
 | 
			
		||||
	return browser.declarativeNetRequest
 | 
			
		||||
		.updateDynamicRules({
 | 
			
		||||
			addRules: rules,
 | 
			
		||||
			removeRuleIds: [],
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			return console.log("User-Agent spoofing rules added successfully.");
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error adding rules:", error);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop user-agent spoofing
 | 
			
		||||
function stopUserAgentSpoofing() {
 | 
			
		||||
	return browser.declarativeNetRequest
 | 
			
		||||
		.updateDynamicRules({
 | 
			
		||||
			removeRuleIds: [1],
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			console.log("User-Agent spoofing rules removed successfully.");
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Clear the bannerInjected flag when stopping the extension
 | 
			
		||||
			return browser.storage.local.set({ bannerInjected: false });
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error removing rules:", error);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
browser.runtime.onStartup.addListener(set_extension_status_OFF);
 | 
			
		||||
browser.browserAction.onClicked.addListener(update_icon);
 | 
			
		||||
// Function to refresh all active tabs
 | 
			
		||||
function refreshAllTabs() {
 | 
			
		||||
	return browser.tabs.query({}).then((tabs) => {
 | 
			
		||||
		tabs.forEach((tab) => {
 | 
			
		||||
			browser.tabs
 | 
			
		||||
				.reload(tab.id)
 | 
			
		||||
				.then(() => {
 | 
			
		||||
					console.log(`Refreshed tab: ${tab.id}`);
 | 
			
		||||
				})
 | 
			
		||||
				.catch((error) => {
 | 
			
		||||
					console.error(`Error refreshing tab ${tab.id}:`, error);
 | 
			
		||||
				});
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
browser.webRequest.onBeforeSendHeaders.addListener(
 | 
			
		||||
    rewrite_user_agent_header,
 | 
			
		||||
    {urls: [target_urls]},
 | 
			
		||||
    ["blocking", "requestHeaders"]
 | 
			
		||||
);
 | 
			
		||||
// Inject the content.js script into all active tabs
 | 
			
		||||
function injectContentScript() {
 | 
			
		||||
	return browser.tabs
 | 
			
		||||
		.query({})
 | 
			
		||||
		.then((tabs) => {
 | 
			
		||||
			return Promise.all(
 | 
			
		||||
				tabs.map((tab) => {
 | 
			
		||||
					// Check if the tab is not a chrome URL
 | 
			
		||||
					if (!tab.url.startsWith("chrome://")) {
 | 
			
		||||
						return browser.scripting
 | 
			
		||||
							.executeScript({
 | 
			
		||||
								target: { tabId: tab.id },
 | 
			
		||||
								files: ["content.js"],
 | 
			
		||||
							})
 | 
			
		||||
							.then(() => {
 | 
			
		||||
								console.log(
 | 
			
		||||
									`Content script injected into tab ${tab.id}`
 | 
			
		||||
								);
 | 
			
		||||
							})
 | 
			
		||||
							.catch((error) => {
 | 
			
		||||
								console.error(
 | 
			
		||||
									`Error injecting content script into tab ${tab.id}:`,
 | 
			
		||||
									error
 | 
			
		||||
								);
 | 
			
		||||
							});
 | 
			
		||||
					} else {
 | 
			
		||||
						console.log(
 | 
			
		||||
							`Skipped injecting content script into tab ${tab.id} (chrome:// URL)`
 | 
			
		||||
						);
 | 
			
		||||
					}
 | 
			
		||||
				})
 | 
			
		||||
			);
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error querying tabs:", error);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove the content from all active tabs
 | 
			
		||||
function removeInjectedContent() {
 | 
			
		||||
	return browser.tabs
 | 
			
		||||
		.query({})
 | 
			
		||||
		.then((tabs) => {
 | 
			
		||||
			tabs.forEach((tab) => {
 | 
			
		||||
				if (!tab.url.startsWith("chrome://")) {
 | 
			
		||||
					browser.scripting
 | 
			
		||||
						.executeScript({
 | 
			
		||||
							target: { tabId: tab.id },
 | 
			
		||||
							function: () => {
 | 
			
		||||
								const banner =
 | 
			
		||||
									document.querySelector(".extension-banner");
 | 
			
		||||
								if (banner && banner.parentNode) {
 | 
			
		||||
									banner.parentNode.removeChild(banner);
 | 
			
		||||
								}
 | 
			
		||||
							},
 | 
			
		||||
						})
 | 
			
		||||
						.then(() => {
 | 
			
		||||
							console.log(
 | 
			
		||||
								`Removed injected content from tab ${tab.id}`
 | 
			
		||||
							);
 | 
			
		||||
						})
 | 
			
		||||
						.catch((error) => {
 | 
			
		||||
							console.error(
 | 
			
		||||
								`Error removing injected content from tab ${tab.id}:`,
 | 
			
		||||
								error
 | 
			
		||||
							);
 | 
			
		||||
						});
 | 
			
		||||
				} else {
 | 
			
		||||
					console.log(
 | 
			
		||||
						`Skipped removing injected content from tab ${tab.id} (chrome:// URL)`
 | 
			
		||||
					);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error(
 | 
			
		||||
				"Error querying tabs for injected content removal:",
 | 
			
		||||
				error
 | 
			
		||||
			);
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Event listeners for Manifest v3 Service Worker
 | 
			
		||||
browser.runtime.onInstalled.addListener(() => {
 | 
			
		||||
	set_extension_status_OFF(); // Set status to OFF on installation/startup
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Handle browser action clicks to toggle status
 | 
			
		||||
browser.action.onClicked.addListener(update_icon);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								1000_bots_webextension/content.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								1000_bots_webextension/content.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
(function () {
 | 
			
		||||
	// Use chrome or browser depending on the environment
 | 
			
		||||
	var browser = chrome || browser;
 | 
			
		||||
 | 
			
		||||
	// Duration to show the banner (in milliseconds)
 | 
			
		||||
	let DISPLAY_DURATION = 5000; // Initialize the duration to 5 seconds
 | 
			
		||||
	let banner; // Declare the banner variable in the outer scope
 | 
			
		||||
 | 
			
		||||
	// Get the duration from local storage and update the DISPLAY_DURATION variable
 | 
			
		||||
	browser.storage.local
 | 
			
		||||
		.get(["duration", "status"]) // Fetch both duration and status
 | 
			
		||||
		.then((result) => {
 | 
			
		||||
			DISPLAY_DURATION = result.duration || DISPLAY_DURATION;
 | 
			
		||||
			console.log("Duration set to:", DISPLAY_DURATION, "(in ms)");
 | 
			
		||||
 | 
			
		||||
			// Set variables to css for delay for animation
 | 
			
		||||
			let CSS_ANIMATION_DURATION = 300 / 1000;
 | 
			
		||||
			let CSS_DURATION = DISPLAY_DURATION / 1000;
 | 
			
		||||
			let CSS_DELAY =
 | 
			
		||||
				CSS_DURATION - CSS_ANIMATION_DURATION - CSS_ANIMATION_DURATION;
 | 
			
		||||
 | 
			
		||||
			console.log("--duration:", `${CSS_ANIMATION_DURATION}s`);
 | 
			
		||||
			console.log("--delay:", `${CSS_DURATION}s`);
 | 
			
		||||
 | 
			
		||||
			CSS_ANIMATION_DURATION = CSS_ANIMATION_DURATION + "s";
 | 
			
		||||
			document.body.style.setProperty(
 | 
			
		||||
				"--duration",
 | 
			
		||||
				CSS_ANIMATION_DURATION
 | 
			
		||||
			);
 | 
			
		||||
 | 
			
		||||
			CSS_DELAY = CSS_DELAY + "s";
 | 
			
		||||
			document.body.style.setProperty("--delay", CSS_DELAY);
 | 
			
		||||
 | 
			
		||||
			if (result.status === 0) {
 | 
			
		||||
				// Extension is OFF, do nothing
 | 
			
		||||
				console.log("Extension is OFF, exiting.");
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (result.bannerInjected) {
 | 
			
		||||
				// Banner has already been injected, do nothing
 | 
			
		||||
				console.log("Banner already injected, exiting.");
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			console.log("Injecting the banner...");
 | 
			
		||||
 | 
			
		||||
			// Inject the CSS file
 | 
			
		||||
			const link = document.createElement("link");
 | 
			
		||||
			link.href = browser.runtime.getURL("style.css");
 | 
			
		||||
			link.rel = "stylesheet";
 | 
			
		||||
			document.head.appendChild(link);
 | 
			
		||||
			console.log("CSS file injected.");
 | 
			
		||||
 | 
			
		||||
			// Create and style the banner container
 | 
			
		||||
			banner = document.createElement("div");
 | 
			
		||||
			banner.classList.add("extension-banner-container");
 | 
			
		||||
 | 
			
		||||
			const marqeeText = "YOU ARE NOW SURFING THE WEB AS A BOT 🤖 ";
 | 
			
		||||
 | 
			
		||||
			const bannerContent = `
 | 
			
		||||
            <div class="banner montserrat">
 | 
			
		||||
                <div class="marquee">
 | 
			
		||||
                    <span class="marquee__inner" style="--ad: 80s;">
 | 
			
		||||
                        ${new Array(30).fill(marqeeText).join("")}
 | 
			
		||||
                    </span>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            `;
 | 
			
		||||
 | 
			
		||||
			// Set the banner content
 | 
			
		||||
			banner.innerHTML = bannerContent;
 | 
			
		||||
 | 
			
		||||
			// Append the banner to the body
 | 
			
		||||
			document.body.appendChild(banner);
 | 
			
		||||
			console.log("Banner injected:", banner);
 | 
			
		||||
 | 
			
		||||
			// Set the flag in local storage to indicate that the banner was injected
 | 
			
		||||
			return browser.storage.local.set({ bannerInjected: true });
 | 
			
		||||
		})
 | 
			
		||||
		.then(() => {
 | 
			
		||||
			// Remove the banner after the specified duration
 | 
			
		||||
			setTimeout(() => {
 | 
			
		||||
				if (banner && banner.parentNode) {
 | 
			
		||||
					banner.parentNode.removeChild(banner);
 | 
			
		||||
					console.log("Banner removed after duration.");
 | 
			
		||||
 | 
			
		||||
					// Reset the flag when the banner is removed
 | 
			
		||||
					browser.storage.local.set({ bannerInjected: false });
 | 
			
		||||
				}
 | 
			
		||||
			}, DISPLAY_DURATION);
 | 
			
		||||
		})
 | 
			
		||||
		.catch((error) => {
 | 
			
		||||
			console.error("Error in content script:", error);
 | 
			
		||||
		});
 | 
			
		||||
})();
 | 
			
		||||
@@ -1,22 +1,50 @@
 | 
			
		||||
{
 | 
			
		||||
  "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/",
 | 
			
		||||
  "name": "1000 Bots",
 | 
			
		||||
  "browser_specific_settings": {
 | 
			
		||||
  "gecko": {
 | 
			
		||||
    "id": "trash@bitnik.org",
 | 
			
		||||
    "strict_min_version": "55.0"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "background": {
 | 
			
		||||
     "scripts": ["background.js"],
 | 
			
		||||
     "persistent": true
 | 
			
		||||
   },
 | 
			
		||||
  "permissions": ["webRequest", "webRequestBlocking", "*://*/*"],
 | 
			
		||||
      "browser_action": {
 | 
			
		||||
      "name": "Click to change your browsers perspective",
 | 
			
		||||
      "default_icon": "icon_OFF_48.png"
 | 
			
		||||
  },
 | 
			
		||||
  "manifest_version": 2
 | 
			
		||||
	"name": "1000 Bots",
 | 
			
		||||
	"version": "0.0.1",
 | 
			
		||||
	"description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?",
 | 
			
		||||
	"homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/",
 | 
			
		||||
	"manifest_version": 3,
 | 
			
		||||
 | 
			
		||||
	"background": {
 | 
			
		||||
		"service_worker": "background.js"
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"permissions": [
 | 
			
		||||
		"storage",
 | 
			
		||||
		"tabs",
 | 
			
		||||
		"scripting",
 | 
			
		||||
		"activeTab",
 | 
			
		||||
		"declarativeNetRequest",
 | 
			
		||||
		"declarativeNetRequestFeedback"
 | 
			
		||||
	],
 | 
			
		||||
 | 
			
		||||
	"host_permissions": ["*://*/*"],
 | 
			
		||||
 | 
			
		||||
	"action": {
 | 
			
		||||
		"default_title": "Click to change your browser's perspective",
 | 
			
		||||
		"default_icon": "icon_OFF_48.png"
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"content_scripts": [
 | 
			
		||||
		{
 | 
			
		||||
			"matches": ["<all_urls>"],
 | 
			
		||||
			"js": ["content.js"],
 | 
			
		||||
			"css": ["style.css"],
 | 
			
		||||
			"run_at": "document_idle"
 | 
			
		||||
		}
 | 
			
		||||
	],
 | 
			
		||||
 | 
			
		||||
	"web_accessible_resources": [
 | 
			
		||||
		{
 | 
			
		||||
			"resources": ["style.css"],
 | 
			
		||||
			"matches": ["<all_urls>"]
 | 
			
		||||
		}
 | 
			
		||||
	],
 | 
			
		||||
 | 
			
		||||
	"browser_specific_settings": {
 | 
			
		||||
		"gecko": {
 | 
			
		||||
			"id": "trash@bitnik.org",
 | 
			
		||||
			"strict_min_version": "55.0"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								1000_bots_webextension/old.background.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								1000_bots_webextension/old.background.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
    1000 Bots - Surf the Web as Googlebot
 | 
			
		||||
 | 
			
		||||
    Copyleft (C) 2020 !Mediengruppe Bitnik, connect@bitnik.org
 | 
			
		||||
 | 
			
		||||
    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var browser = browser || chrome
 | 
			
		||||
var user_agent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
 | 
			
		||||
var target_urls = "*://*/*";
 | 
			
		||||
var status = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function set_extension_status_ON() {
 | 
			
		||||
    status = 1;
 | 
			
		||||
    //console.log('Setting status to ON');
 | 
			
		||||
    browser.browserAction.setIcon({path: 'icon_ON_48.png'});
 | 
			
		||||
    browser.browserAction.setTitle({title: "1000 Bots"});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function set_extension_status_OFF() {
 | 
			
		||||
    status = 0;
 | 
			
		||||
    //console.log('Setting status to OFF');
 | 
			
		||||
    browser.browserAction.setIcon({path: 'icon_OFF_48.png'});
 | 
			
		||||
    browser.browserAction.setTitle({title: "1000 Bots activate"});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function update_icon(){
 | 
			
		||||
    if(status == 0) {
 | 
			
		||||
        set_extension_status_ON();
 | 
			
		||||
    }else{
 | 
			
		||||
        set_extension_status_OFF();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function rewrite_user_agent_header(e){
 | 
			
		||||
    
 | 
			
		||||
    //console.log('Browser http request!');
 | 
			
		||||
 | 
			
		||||
    if(status == 0) {
 | 
			
		||||
        // console.log('Nothing to do');
 | 
			
		||||
        return {requestHeaders: e.requestHeaders};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (var header of e.requestHeaders) {
 | 
			
		||||
        if (header.name.toLowerCase() === "user-agent") {
 | 
			
		||||
            header.value = user_agent;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    //console.log('Set user-agent header to: ' + user_agent);
 | 
			
		||||
    return {requestHeaders: e.requestHeaders};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
browser.runtime.onStartup.addListener(set_extension_status_OFF);
 | 
			
		||||
browser.browserAction.onClicked.addListener(update_icon);
 | 
			
		||||
 | 
			
		||||
browser.webRequest.onBeforeSendHeaders.addListener(
 | 
			
		||||
    rewrite_user_agent_header,
 | 
			
		||||
    {urls: [target_urls]},
 | 
			
		||||
    ["blocking", "requestHeaders"]
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										22
									
								
								1000_bots_webextension/old.manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								1000_bots_webextension/old.manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
{
 | 
			
		||||
  "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/",
 | 
			
		||||
  "name": "1000 Bots",
 | 
			
		||||
  "browser_specific_settings": {
 | 
			
		||||
  "gecko": {
 | 
			
		||||
    "id": "trash@bitnik.org",
 | 
			
		||||
    "strict_min_version": "55.0"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "background": {
 | 
			
		||||
     "scripts": ["background.js"],
 | 
			
		||||
     "persistent": true
 | 
			
		||||
   },
 | 
			
		||||
  "permissions": ["webRequest", "webRequestBlocking", "*://*/*"],
 | 
			
		||||
      "browser_action": {
 | 
			
		||||
      "name": "Click to change your browsers perspective",
 | 
			
		||||
      "default_icon": "icon_OFF_48.png"
 | 
			
		||||
  },
 | 
			
		||||
  "manifest_version": 2
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										171
									
								
								1000_bots_webextension/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								1000_bots_webextension/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap");
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
	--main-bg-color: black;
 | 
			
		||||
	--main-color: white;
 | 
			
		||||
	--bg: #8f8f8f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.montserrat {
 | 
			
		||||
	font-family: "Montserrat", sans-serif;
 | 
			
		||||
	font-optical-sizing: auto;
 | 
			
		||||
	font-weight: 800;
 | 
			
		||||
	font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.extension-banner-container {
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	top: 0;
 | 
			
		||||
	left: 0;
 | 
			
		||||
	width: 100vw;
 | 
			
		||||
	height: 100vh; /* Full screen height */
 | 
			
		||||
	background-color: transparent;
 | 
			
		||||
	z-index: 9999; /* High z-index to ensure it blocks everything below */
 | 
			
		||||
	display: flex;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	pointer-events: none; /* Allow clicks to pass through */
 | 
			
		||||
	background: linear-gradient(var(--main-color), var(--bg));
 | 
			
		||||
	opacity: 0;
 | 
			
		||||
	/* fade-in and fade-out for the screen take-over */
 | 
			
		||||
	animation: var(--duration) ease-in-out var(--duration) 1 normal forwards
 | 
			
		||||
			show,
 | 
			
		||||
		var(--duration) ease-in-out var(--delay) 1 reverse forwards show;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes show {
 | 
			
		||||
	0% {
 | 
			
		||||
		opacity: 0;
 | 
			
		||||
	}
 | 
			
		||||
	100% {
 | 
			
		||||
		opacity: 0.8;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.banner {
 | 
			
		||||
	background: var(--main-bg-color);
 | 
			
		||||
	color: var(--main-color);
 | 
			
		||||
	position: relative;
 | 
			
		||||
	padding: 1rem;
 | 
			
		||||
	font-size: 5rem;
 | 
			
		||||
	line-height: 11rem;
 | 
			
		||||
	transform: rotate(-25deg); /* Rotates the banner */
 | 
			
		||||
	width: 200vw; /* Extra-wide to ensure the marquee scrolls smoothly across */
 | 
			
		||||
	height: auto;
 | 
			
		||||
 | 
			
		||||
	/* Apply gradients to the banner itself */
 | 
			
		||||
	/* Add a left-to-transparent gradient on the left */
 | 
			
		||||
	/* Add a right-to-transparent gradient on the right */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.banner::before,
 | 
			
		||||
.banner::after {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	top: 0;
 | 
			
		||||
	z-index: 9999;
 | 
			
		||||
	width: 15%;
 | 
			
		||||
	height: 100%;
 | 
			
		||||
	content: "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.banner::before {
 | 
			
		||||
	left: 0;
 | 
			
		||||
	background: linear-gradient(to right, var(--main-bg-color), transparent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.banner::after {
 | 
			
		||||
	right: 0;
 | 
			
		||||
	background: linear-gradient(to left, var(--main-bg-color), transparent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.marquee {
 | 
			
		||||
	overflow: hidden;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.marquee__inner {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	white-space: nowrap;
 | 
			
		||||
	/* Adjust the speed using --ad which can be set dynamically in the HTML */
 | 
			
		||||
	animation: scroll var(--ad, 100s) linear infinite;
 | 
			
		||||
	transform: translate3d(0, 0, 0); /* Force hardware acceleration */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.marquee span {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	padding-right: 2rem; /* Add some space between each repeat */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Keyframes to make the animation appear infinite without gaps */
 | 
			
		||||
@keyframes scroll {
 | 
			
		||||
	0% {
 | 
			
		||||
		transform: translate3d(
 | 
			
		||||
			-50%,
 | 
			
		||||
			0,
 | 
			
		||||
			0
 | 
			
		||||
		); /* Start in the middle of the loop */
 | 
			
		||||
	}
 | 
			
		||||
	100% {
 | 
			
		||||
		transform: translate3d(-100%, 0, 0); /* Move left but only 50% */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Mobile screens */
 | 
			
		||||
@media (max-width: 30rem) {
 | 
			
		||||
	.extension-banner-container {
 | 
			
		||||
		width: 110vw;
 | 
			
		||||
		height: 110vh;
 | 
			
		||||
	}
 | 
			
		||||
	.banner {
 | 
			
		||||
		transform: rotate(-60deg);
 | 
			
		||||
		width: 250vw;
 | 
			
		||||
		margin-left: -15rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Tablet screens */
 | 
			
		||||
@media (min-width: 48rem) {
 | 
			
		||||
	.banner {
 | 
			
		||||
		transform: rotate(-50deg);
 | 
			
		||||
		width: 225vw;
 | 
			
		||||
		margin-left: -5rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* iPad Mini */
 | 
			
		||||
@media (min-width: 48rem) and (max-width: 64rem) and (orientation: landscape) {
 | 
			
		||||
	.banner {
 | 
			
		||||
		transform: rotate(-40deg);
 | 
			
		||||
		width: 225vw;
 | 
			
		||||
		margin-left: -5rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Laptop screens */
 | 
			
		||||
@media (min-width: 64rem) {
 | 
			
		||||
	.extension-banner-container {
 | 
			
		||||
		width: 115vw;
 | 
			
		||||
		height: 115vh;
 | 
			
		||||
	}
 | 
			
		||||
	.banner {
 | 
			
		||||
		transform: rotate(-30deg);
 | 
			
		||||
		width: 210vw;
 | 
			
		||||
		margin-left: -5rem;
 | 
			
		||||
		margin-top: -5rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Desktop screens */
 | 
			
		||||
@media (min-width: 80rem) {
 | 
			
		||||
	.extension-banner-container {
 | 
			
		||||
		width: 115vw;
 | 
			
		||||
		height: 115vh;
 | 
			
		||||
	}
 | 
			
		||||
	.banner {
 | 
			
		||||
		transform: rotate(-32deg);
 | 
			
		||||
		width: 200vw;
 | 
			
		||||
		margin-left: -15rem;
 | 
			
		||||
		margin-top: -15rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user