Chrome extension crashes when trying to access from two different windows? - javascript

I open a chrome extension, then open a new window (incognito for example) and try to open the extension again, it crashes. I then need to reload the app through the chrome extensions page. There are no errors in this.
The question is how can I work with the extension from different windows at the same time
{
"manifest_version": 2,
"name": "Such Activity",
"description": "Wow",
"version": "1.0",
"permissions": ["tabs","webRequest", "webRequestBlocking", "storage", "http://*/","https://*/"],
"browser_action": {
"default_title": "Click Me",
"default_popup": "popup.html",
"default_icon": "start.png"
}
}
and my popup.js
function injectTheScript() {
console.log("start script")
if (nfts.length <= 0) {
console.log("successfull")
return;
}
id = nfts.pop()
var newURL = "url"+id;
chrome.tabs.update({url: newURL}, myTab => {
function listener(tabId, changeInfo, tab) {
if (tabId === myTab.id && changeInfo.status == 'complete') {
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
chrome.tabs.executeScript(tab.id, {file: "content_script.js"});
})
counter++;
document.getElementById('count').textContent = counter
console.log("hoba"+counter)
setTimeout(injectTheScript, 7000);
}
};
if (!isInjected) {
chrome.tabs.onUpdated.addListener(listener);
isInjected = true;
}
});
}
document.getElementById('clickactivity').addEventListener('click', injectTheScript)
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return { cancel: true };
},
{urls: ["*://*/*checkUser"]},
["blocking"]
);
the extension crashes before I interact with it. it crashes when i click on its icon in chrome

It's a bug in stable version Chrome, it's fixed in Chrome Canary
thx wOxxOm for

Related

Cant fire `alert` from `service_worker` (previously background) from Chrome Extension (v3 manifest) [duplicate]

I am attempting to display an alarm that pops up in my browser from background.js in Manifest v3. However, using the code implementation that is described in the Manifest v3 page does not produce an alarm.
Manifest.js:
{
"name": "Focus-Bot",
"description": "A bot meant to help you focus",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["storage", "activeTab", "scripting"],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/get_started16.png",
"32": "/images/get_started32.png",
"48": "/images/get_started48.png",
"128": "/images/get_started128.png"
}
},
"icons": {
"16": "/images/get_started16.png",
"32": "/images/get_started32.png",
"48": "/images/get_started48.png",
"128": "/images/get_started128.png"
},
"options_page": "options.html"
}
Background.js:
chrome.runtime.onInstalled.addListener(() => {
chrome.scripting.executeScript({
function: showAlert
})
});
function showAlert(){
alert('object input for later');
}
This version of background.js returns the following error
TypeError: Error in invocation of scripting.executeScript(scripting.ScriptInjection injection, optional function callback): Error at parameter 'injection': Missing required property 'target'.
The example code of a working Chrome Extension (the green background button) uses chrome.tabs in a popup.js file to get a target and inject javascript, but when background.js runs the same code like this:
Background.js (tabs):
chrome.runtime.onInstalled.addListener(() => {
let [tab] = await chrome.tabs.query(queryOptions);
console.log(tab)
chrome.scripting.executeScript({
function: showAlert
})
});
function showAlert(){
alert('object input for later');
}
Background.js seems to crash with "Service worker registration failed", with no error logs.
How do I display an alarm for the current active page from background.js?
As the error message says you need to add target to executeScript's parameters. Always look up the exact usage of API methods in the documentation.
Your code uses await but the function isn't declared with async which is a syntax error that causes the service worker to fail the registration. Currently ManifestV3 is riddled with bugs so it doesn't even show the cause of the failure so you'll have to use try/catch manually.
try {
chrome.runtime.onInstalled.addListener(async () => {
const [tab] = await chrome.tabs.query(queryOptions);
chrome.scripting.executeScript({
target: {tabId: tab.id},
function: showAlert,
});
});
} catch (e) {
console.error(e);
}
An arguably better/cleaner approach would be to use two files: the main code in bg.js and the try-catch wrapper in bg-loader.js that imports bg.js, see this example.
Note that the active tab may be un-injectable e.g. a default start page or a chrome:// page (settings, bookmarks, etc.) or a chrome-extension:// page. Instead you can open a small new window:
alert({html: 'Foo <b>bar</b><ul><li>bla<li>bla</ul>'})
.then(() => console.log('alert closed'));
async function alert({
html,
title = chrome.runtime.getManifest().name,
width = 300,
height = 150,
left,
top,
}) {
const w = left == null && top == null && await chrome.windows.getCurrent();
const w2 = await chrome.windows.create({
url: `data:text/html,<title>${title}</title>${html}`.replace(/#/g, '%23'),
type: 'popup',
left: left ?? Math.floor(w.left + (w.width - width) / 2),
top: top ?? Math.floor(w.top + (w.height - height) / 2),
height,
width,
});
return new Promise(resolve => {
chrome.windows.onRemoved.addListener(onRemoved, {windowTypes: ['popup']});
function onRemoved(id) {
if (id === w2.id) {
chrome.windows.onRemoved.removeListener(onRemoved);
resolve();
}
}
});
}

setInterval in Chrome extension in background.js

There have been quite a few similar questions on setInterval in background.js in a Chrome extension but none of the answers worked for me. I have a simple extension that checks connectivity to a server by calling an API and checking whether there is a 200 response and then updating the extension icon in the tray accordingly.
background.js
chrome.runtime.onInstalled.addListener(() => {
chrome.browserAction.setIcon({path: "/images/checking.png"});
console.log('VPN check extension started');
// main block - make API calls periodically and monitor the server response
async function ping() {
try {
const response = await axios.get('http://[IP]/api/v1/ping', {
timeout: 4000
});
access = response.status;
if (access == 200) {
chrome.browserAction.setIcon({path: "/images/OK_53017.png"});
} else {
chrome.browserAction.setIcon({path: "/images/not_OK.png"});
}
} catch (error) {
chrome.browserAction.setIcon({path: "/images/not_OK.png"});
}
}
window.setInterval(ping, 1000 * 10);
});
chrome.runtime.onStartup.addListener(() => {
chrome.browserAction.setIcon({path: "/images/checking.png"});
console.log('VPN check extension started');
// main block - make API calls periodically and monitor the server response
async function ping() {
try {
const response = await axios.get('http://[IP]/api/v1/ping', {
timeout: 4000
});
access = response.status;
if (access == 200) {
chrome.browserAction.setIcon({path: "/images/OK_53017.png"});
} else {
chrome.browserAction.setIcon({path: "/images/not_OK.png"});
}
} catch (error) {
chrome.browserAction.setIcon({path: "/images/not_OK.png"});
console.log('error');
}
}
window.setInterval(ping, 1000 * 10);
});
Neither onStartup nor onInstalled works well - when I restart Chrome or switch windows the extension becomes unresponsive.
Manifest
{
"name": "Access status",
"version": "0.0.3",
"description": "Chrome extension to check if access to the network is provided.",
"background": {
"scripts": ["axios.min.js", "background.js"],
"persistent": false
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/checking.png"
},
"icons": {
"16": "images/checking.png"
}
},
"permissions": ["<all_urls>"],
"manifest_version": 2,
}
content.js is empty
Any suggestion how to make it work, regardless of which tab is in focus or which window is open and get it to set the interval when fresh Chrome opens? Thanks
A quick google brought up this post. Basically you should probably try using the alarms API instead since chrome will just kill your background script in order to optimize performance.
Your code would probably work at least until someone restarts the browser if you had the background as persistent: true. However that option seems to be deprecated now.

How To Call Chrome Extension Function After Page Redirect?

I am working on building a Javascript (in-browser) Instagram bot. However, I ran into a problem.
If you run this script, the first function will be called and the page will be redirected to "https://www.instagram.com/explore/tags/samplehashtag/" and the second function will be called immediately after (on the previous URL before the page changes to the new URL). Is there a way to make the second function be called after this second URL has been loaded completely?
I have tried setting it to a Window setInterval() Method for an extended time period, window.onload and a couple of other methods. However, I can't seem to get anything to work. Any chance someone has a solution?
This is my first chrome extension and my first real project, so I may be missing something simple..
manifest.json
{
"name": "Inject Me",
"version": "1.0",
"manifest_version": 2,
"description": "Injecting stuff",
"homepage_url": "http://danharper.me",
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
"browser_action": {
"default_title": "Inject!"
},
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
]
}
inject.js
(function() {
let findUrl = () => {
let hashtag = "explore/tags/samplehashtag/";
location.replace("https://www.instagram.com/" + hashtag);
}
findUrl();
})();
background.js
// this is the background code...
// listen for our browerAction to be clicked
chrome.browserAction.onClicked.addListener(function(tab) {
// for the current tab, inject the "inject.js" file & execute it
chrome.tabs.executeScript(tab.ib, {
file: 'inject.js'
});
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.executeScript(tab.ib, {
file: 'inject2.js'
});
});
inject2.js
(function() {
if (window.location.href.indexOf("https://www.instagram.com/explore/tags/samplehashtag/") != -1){
let likeAndRepeat = () => {
let counter = 0;
let grabPhoto = document.querySelector('._9AhH0');
grabPhoto.click();
let likeAndSkip = function() {
let heart = document.querySelector('.glyphsSpriteHeart__outline__24__grey_9.u-__7');
let arrow = document.querySelector('a.coreSpriteRightPaginationArrow');
if (heart) {
heart.click();
counter++;
console.log(`You have liked ${counter} photographs`)
}
arrow.click();
}
setInterval(likeAndSkip, 3000);
//alert('likeAndRepeat Inserted');
};
likeAndRepeat();
}
})();
It is not clear from the question and the example, when you want to run your function. But in chrome extension there is something called Message Passing
https://developer.chrome.com/extensions/messaging
With message passing you can pass messages from one file to another, and similarly listen for messages.
So as it looks from your use case, you can listen for a particular message and then fire your method.
For example
background.js
chrome.runtime.sendMessage({message: "FIRE_SOME_METHOD"})
popup.js
chrome.runtime.onMessage.addListener(
function(request) {
if (request.message == "FIRE_SOME_METHOD")
someMethod();
});
EDIT
Also if you want to listen for the URL changes, you can simply put a listener provided as in the documentation.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
console.log('updated tab');
});

Why is window.open() and window.close() not working in Extension?

Alright so I'm currently in the process of trying to automate some tasks via a chrome extension. Here are all my files, the issue is with my content.js:
manifest.json:
{
"manifest_version": 2,
"name": "Click to execute",
"description": "Execute script after click in popup.html (chrome extension) http://stackoverflow.com/questions/20764517/execute-script-after-click-in-popup-html-chrome-extension.",
"version": "1.0",
"icons": {
"48": "icon.png"
},
"permissions": [
"tabs", "<all_urls>"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
popup.html:
<!DOCTYPE html>
<html>
<body style="width: 300px">
Open this page and then
<button id="clickme">click me</button>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>
popup.js:
function hello() {
chrome.tabs.executeScript({
file: 'content.js'
});
}
document.getElementById('clickme').addEventListener('click', hello);
content.js:
let firstCl = function(){
document.getElementsByClassName('nav-link')[6].click();
};
let openWin = function(){
window.open('www.google.com');
};
let closeWin = function(){
window.close()
}
setTimeout(firstCl, 3000);
setTimeout(openWin, 6000);
setTimeout(closeWin, 9000);
Im trying to click on a link, then open a new tab with google.com, then wait a while and close that tab automatically. For some reason the window.close(); method inst doing anything, google opens and then just stays open. Any ideas?
So two things I see that will help you out.
If you want a new tab to open you will need to do add '_blank' otherwise it will just take over the current window. so window.open('www.google.com', '_blank');
You need to reference the window you opened. So assign it to a variable and then close that specific window that was spawned
let theWindow;
let firstCl = function() {
document.getElementsByClassName('nav-link')[6].click();
};
let openWin = function() {
theWindow = window.open('www.google.com', '_blank');
};
let closeWin = function() {
theWindow.close()
}
setTimeout(firstCl, 3000);
setTimeout(openWin, 6000);
setTimeout(closeWin, 9000);

How do I stop content script execution in the current tab?

I'm working on a Google Chrome Extension, and I'm encountering a bug I can't solve on my own.
It works as expected switching to Youtube's Dark Mode on a single Youtube tab, but if you're on Youtube and Ctrl/Cmd click a link (open in a new tab), content.js is triggered again and the current tab is turned white and the new tab is dark.
If you are in a dark tab, a "child" tab should automatically be dark.
manifest.json:
{
"manifest_version": 2,
"permissions": [
"https://www.youtube.com/*",
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistant": false
},
"browser_action": {
"default_title": "Engage Youtube Dark Mode."
},
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["content.js"]
}]
}
background.js:
//var alreadyTriggered = false;
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "clicker.js"});
});
/*
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
alreadyTriggered = false;
});*/
chrome.runtime.onMessage.addListener(function(response, sender, sendResponse) {
//if (!alreadyTriggered) {
chrome.tabs.executeScript(null, {file: "clicker.js"});
//alreadyTriggered = true;
//};
return true;
});
content.js:
var myDate = new Date();
if ((myDate.getHours() <= 7) || (myDate.getHours() >= 19))
{
var darkMode = document.body.getAttribute("dark");
if (!darkMode) {
chrome.runtime.sendMessage(window.location.href, function(result) {});
};
};
I'm guessing that I'm using activeTab incorrectly. Any help would be greatly appreciated. Thanks!
clicker.js:
stepOne();
function stepOne() {
try {
var buttons = document.querySelectorAll("button.ytd-topbar-menu-button-renderer");
buttons[0].click();
stepTwo();
}
catch(error) {
setTimeout(stepOne, 250);
}
}
function stepTwo() {
try {
buttons = document.querySelectorAll("paper-item.ytd-account-settings");
buttons[0].click();
stepThree();
}
catch(error) {
setTimeout(stepTwo, 100);
}
}
function stepThree() {
try {
buttons = document.querySelectorAll("paper-toggle-button.style-scope.ytd-account-settings");
buttons[0].click();
document.body.click();
}
catch(error) {
setTimeout(stepThree, 100);
}
}
What ended up working for me was to use a combination of:
using window.onload = doStuff();
And to make sure that the value for darkMode was null, not undefined.
Hopefully this helps someone who's been endlessly tweaking their code.

Categories

Resources