Chrome extension: chrome.scripting.executeScript not working - google-chrome

for some reason my executeScript function is not working.
This is my code:
async function scrape_get_url(){
console.log("Getting url: " + from_url);
var tab_id;
chrome.tabs.create({ "url": from_url}, function(newTab){
tab_id = newTab.id;
console.log("Checking for tab url update");
});
chrome.tabs.onUpdated.addListener( function(tabId, info) {
if(tabId == tab_id && info.url){
console.log("Executing scrape script");
console.log("tab id:" + tab_id);
console.log("updated tab url:" + info.url);
chrome.scripting.executeScript({
target: {tabId: tab_id},
function: scrape
});
}
});
}
function scrape(){
console.log("Getting Element...");
}
This is my output:
Getting url: https://developer.chrome.com/docs/extensions/mv3/getstarted
Checking for tab url update
Executing scrape script
tab id:293
updated tab url:https://developer.chrome.com/docs/extensions/mv3/getstarted/
I have an onUpdated listener due to a chrome bug, as stated here. Also, the reason I put the onUpdated function outside of the create function's callback, is because according to another question on StackOverflow(that I can't find anymore :/ ), putting the executeScript within the create's callback will not run the script.
My permissions are set correctly in the manifest file.

Related

How to get webstore URL passed to extension despite "webstore cannot be scripted by extensions"

After extensive searching I discovered Rob's answer: https://stackoverflow.com/a/11614440/7907844 that "webstore cannot be scripted by extensions".
I only want to extract the URL and pass it to the extension. Is there no way to achieve this?
Could I query all opened tabs from background script, and keep the active tab URL in a variable accessible to extension?
I ended up implementing background script that saves currently active tab URL in a variable that I access from within a popup.js because webstore doesn't allow us to run content scripts there. chrome.extension.getBackgroundPage() inside popup.js only worked when I used var currentUrl.
var currentUrl;
var activeTabId;
chrome.tabs.onUpdated.addListener(
function (tabId, changeInfo, tab) {
if (changeInfo.status === "complete") {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
let activeTab = tabs[0];
currentUrl = activeTab.url;
activeTabId = activeTab.id;
if(currentUrl.includes("chrome.google.com/webstore/detail")) {
chrome.pageAction.show(activeTab.id);
} else {
chrome.pageAction.hide(activeTab.id);
}
console.log("page loaded: ", currentUrl);
});
}
});
chrome.tabs.onActivated.addListener(function (object) {
activeTabId = object.tabId;
chrome.tabs.get(activeTabId, function(tab){
currentUrl = tab.url;
if(tab.url.includes("chrome.google.com/webstore/detail")) {
chrome.pageAction.show(object.tabId);
} else {
chrome.pageAction.hide(object.tabId);
}
console.log("loaded tab selected: ", tab.url);
})
});

chrome ext many loads on update page

In app use content script for all pages, and send message to active page on complete loaded page, but I have many calls of script sometimes 2 and more:
You can see that here
Code implimentation:
chrome.tabs.onCreated.addListener(function (tabs) {
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if(changeInfo.status === "complete") {
let tabid = tab.id;
console.log("Site is valid: url -> " + tab.url)
chrome.tabs.executeScript(tab.id, {
file: '/injections/mobile.bet365.com.js',
});
console.log(tab);
setTimeout(function () {
console.log("timeout was set")
chrome.tabs.query({}, function (tabs) {
let countOpenedTabsFrom = tabs.length;
let opener = 1;
// на целевой вкладке
chrome.tabs.sendMessage(tabid, {
message: "start_app",
opener: opener,
queuenumber: countOpenedTabsFrom
}, function (response) {
console.log(response);
});
});
}, 500);
}
And executed script have many queries too.
Why is this happen?
Every time onCreated event fires, you're adding a new onUpdated listener.
When, after that, onUpdated event fires, all of them are executed, leading to the behavior you're seeing.
You either need to de-register the handlers when they are done, or register the handler only once. See chrome.events docs (which describe common points of all event objects in other APIs) for ideas on how to implement that.
Note that the code inside chrome.tabs.onCreated listener does not use the tabs parameter at all, so it's not clear why do you even need to listen to onCreated.

Chrome extension create new tab and send message from popup.js to content script of new tab

I am developing a chrome extension where my popup.js receives a message from a content script on the current page and creates an array. Then on a button press, popup.js creates a new tab (which has a content script running) and sends that content script a message containing the array.
My popup.js:
//this message is sent from a different content script (for current page), not shown here
chrome.runtime.onMessage.addListener(function(request, sender) {
if (request.action === "getSource") {
var arr = JSON.parse(request.source);
//create new tab
chrome.tabs.create({url: "newtab.html"}, function(tab){
//send message to new tab
chrome.tabs.sendMessage(tab.id{
action: "getDataArray",
source: JSON.stringify(arr)
});
}
});
newtab-contentscript.js:
$(document).ready( function() {
chrome.runtime.onMessage.addListener(function(request, sender) {
if (request.action === "getDataArray") {
$("#result").html(JSON.parse(request.source));
}
});
newtab.html:
<script src="newtab-contentscript.js"></script>
Problem: The newtab-contentscript.js never seems to receive the message.
Are the any mistakes with how I am creating a tab or sending the message. Do you have any suggestions to how to fix this issue?
As we discussed in the comments, I guess maybe $(document).ready is too late to receive messages from chrome.tabs.sendMessage, you can test it by comparing timestamps of console.log inside the callback and on the first line of the new tab's content scripts, as #wOxxOm mentioned.
I just suggest moving message logic to background (event) page and starting the message passing from newtab-contentscript.js, in which you could control when to start sending the message.
A sample code
background.js
let source = null;
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// sent from another content script, intended for saving source
if(request.action === 'putSource') {
source = request.source;
chrome.tabs.create({ url: 'newtab.html' });
}
// sent from newtab-contentscript, to get the source
if(request.action === 'getSource') {
sendResponse({ source: source });
}
});
newtab-contentscript.js
chrome.runtime.sendMessage({action: 'getSource'}, function(response) {
$('#result').html(response.source);
});

Chrome API : Reloading current tab with a url using method in Content.js

I want to reload the page with url by scanning content of it. I designed this method in javascript to see if the url has specific stirng in it
Content.Js
function init() {
var d = document.location.href;
d = toggleDevMode(d);
return d;
}
function toggleDevMode(url) {
var hasDevModeOn = '?core.apexpages.devmode.url=1';
if (url.indexOf(hasDevModeOn) != -1) {
//toggle
url = url.substring(0, url.lastIndexOf(hasDevModeOn));
} else if (url.indexOf("salesforce.com") == -1) {
url = url + hasDevModeOn;
} else {
url = url;
}
return url;
}
Functionality I want
I want if user click on icon, it run the script calling method I defined in content.js onClick Event and checks url.
Based on Logic I defined here, url will be modified.
I want reload the tab with modified url. I tried this piece of code
chrome.browserAction.onClicked.addListener(function (activeTab) {
var newURL = init();
chrome.tabs.create({
url: newURL
});
});
But it doesn't work. Please advice how can I call these method onclick event
You don't need a content script to do this. Discard your init function. Put your toggleDevMode function together with the following code in a background script. Make sure your manifest specify the activeTab permission.
chrome.browserAction.onClicked.addListener(function (activeTab) {
var newURL = toggleDevMode(activeTab.url);
chrome.tabs.update({
url: newURL
});
});
EDIT: Replace your current permissions section from your manifest by the following:
"permissions": [
"activeTab"
],

Sending message from popup.js in Chrome extension to background.js

What is the proper way to send a message (and get a response) to background.js from popup.js in a Chrome extension? Every method I try ends up with an error that:
"Port: Could not establish connection. Receiving end does not exist."
I would prefer to use chrome.extension.sendMessage() over chrome.extension.connect() with port.postMessage(), but neither method seems to have worked.
What I am trying to do is wire a button in the popup.html to call into some javascript in popup.js which calls back to background.js in an effort to get info about the currentTab() that was topMost (ie:to get the current URL string to show in the popup.html)
Right now in popup.js (wired to the action of the button) I have:
function getURL()
{
chrome.extension.sendMessage({greeting: "GetURL"},
function(response) { tabURL = response.navURL });
$("#tabURL").text(tabURL);
}
In background.js I have:
chrome.extension.onMessage.addListener( function(request,sender,sendResponse)
{
if( request.greeting == "GetURL" )
{
var tabURL = "Not set yet";
chrome.tabs.getCurrent(function(tab){
tabURL = tab.url;
});
sendResponse( {navURL:tabURL} );
}
}
Any ideas?
Just to clarify, we talking about communication between popup page from browserAction and background script?
Anyway you have quite a few errors in your code.
First your totally ignore the fact that all callbacks in chrome api are asynchronous.
In background page
var tabURL = "Not set yet";
chrome.tabs.getCurrent(function(tab){
tabURL = tab.url;
}); //this will be invoked somewhere in the future
sendResponse( {navURL:tabURL} );
//navUrl will be always Not set yet because callback of getCurrent hasn't been called yet
Same in popup.js
chrome.runtime.sendMessage({greeting: "GetURL"},
function(response) { tabURL = response.navURL });//callback will be invoked somewhere in the future
$("#tabURL").text(tabURL)//tabURL will display something totally different from what you have been expected
Second error is that chrome.tabs.getCurrent doesn't give you the current tab selected by user in main window. The docs says:
Gets the tab that this script call is being made from. May be
undefined if called from a non-tab context (for example: a background
page or popup view).
So you will get undefined for all of your requests, because you call it in background page. What you need to do is to use method chrome.tabs.query to obtain currently active tabs.
So after fixing all problems new code should look something like this:
background.js
chrome.runtime.onMessage.addListener( function(request,sender,sendResponse)
{
if( request.greeting === "GetURL" )
{
var tabURL = "Not set yet";
chrome.tabs.query({active:true},function(tabs){
if(tabs.length === 0) {
sendResponse({});
return;
}
tabURL = tabs[0].url;
sendResponse( {navURL:tabURL} );
});
}
}
popup.js
function getURL() {
chrome.runtime.sendMessage({greeting: "GetURL"},
function (response) {
tabURL = response.navURL;
$("#tabURL").text(tabURL);
});
}