chrome.tabs.executeScript doesn't work on load - google-chrome

I am trying to load content script from the background one. the execute function works in the icon click block, but i can't trigger the auto load part
var toggle = false;
//Works
chrome.browserAction.onClicked.addListener(function(tab) {
toggle = !toggle;
if (!toggle){
chrome.browserAction.setIcon({path: "enabled.png"});
}else{
chrome.browserAction.setIcon({path: "disabled.png"});
chrome.tabs.executeScript(null, { file: "script.js" });
// chrome.tabs.executeScript({file : "script.js"});
}
});
//Doesn't work
chrome.tabs.onUpdated.addListener(function(tab) {
chrome.tabs.executeScript(null,{
file: 'script.js'
});
});

The activeTab permission only grants access to to the currently active tab when the user invokes the extension - for example by clicking its browser action.
If you want to execute a script on any arbitrary tab without user intervention, then you'll need the <all_urls> permission.

Related

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.

Clicking, pasting text and uploading files from extension

So I'm basically developing an automated click-paste-and-upload system for mutiple texts and files inside a google page.
This method helped me get the instances of objects that I'm looking for: buttons, textboxes, richtextboxes, etc.
Now I want to work with them.
So for example I know the id of a button , and the function subscribed to its click event. How do I trigger the click event from the extension ? I've tried injecting a script with the click event handler (discovered with DOM inspector) at "document_startup" but I don't get an error or anything else.
Here's the content script! The loggerhead function should have inserted the script but I don't think it did. What might be the reason for the blow code not giving anything?
// Runs a function for every added DOM element that matches a filter
// filter -- either function(DOM_node){/*...*/}, returns true or false
// OR a jQuery selector
// callback -- function(DOM_node){/*...*/}
function watchNodes(filter, callback){
observer = new MutationObserver( function (mutations) {
mutations.forEach( function (mutation){
if(typeof filter === "function"){
$(mutation.addedNodes).filter(
function(i){ return filter(this); }
).each(
function(i){ callback(this); }
);
} else {
$(mutation.addedNodes).filter(filter).each(
function(i){ callback(this); }
);
}
});
});
// For every added element, a mutation will be processed
// with mutation.taget == parent
// and mutation.addedNodes containing the added element
observer.observe(document, { subtree: true, childList: true });
}
function loggerhead(node) {
console.log("passhead");
//also inject jquery
var jqueryEl = document.createElement('script');
jqueryEl.setAttribute('src', chrome.extension.getURL('jquery-1.11.1.min.js'));
jqueryEl.setAttribute('type', 'text/javascript');
var scriptEl = document.createElement('script');
scriptEl.setAttribute('src', chrome.extension.getURL('script.js'));
scriptEl.setAttribute('type', 'text/javascript');
node.appendChild(jqueryEl);
node.appendChild(scriptEl);
}
watchNodes("head", loggerhead);
// method not working
//var gmailHead = jQuery("head", document).get(0);
script.js contains the function of subscribed to the click event of the button that I've managed to find through the DOM inspector:
function Cdb(b){return function(){if(Vbb()){return Ddb(b,this,arguments)}else{var a=Ddb(b,this,arguments);a!=null&&(a=a.val);return a}}}
You should try to call the existing click handler like
buttonElement.click()

pass dom element from background script to chrome.tabs.executeScript

I'm trying to pass the active dom element when the contextmenu is clicked from my background script to a script that is being called through chrome.tabs.executeScript. I can pass booleans and strings just fine, but i always get an error when i pass dom elements. I'm starting to think it's not possible.
//doScripts function called from browser action
chrome.browserAction.onClicked.addListener(function(tab) {
doScripts(true, null);
});
//doScripts function called from context menu click
function getClickHandler(info, tab) {
var currTarg = document.activeElement;
console.log("currTarg = " + currTarg);
doScripts(false, currTarg);
}
//i reference doingBrowserAction and contextTarg in myscript.js
function doScripts(context, targ){
chrome.tabs.executeScript(null, {code: "var doingBrowserAction = "+context+"; var contextTarg = "+targ+";"}, function(){
chrome.tabs.executeScript(null, {file: "js/myscript.js"}, function(){
//all injected
});
});
}
//setup context menu
chrome.contextMenus.create({
"title" : "DESTROY!",
"type" : "normal",
"contexts" : ["page","selection","link","editable","image","video","audio"],
"onclick" : getClickHandler
});
i reference doingBrowserAction and contextTarg in myscript.js. I know what i'm trying to do is possible because the adblock extension does it, but having a hard time figuring out how. thanks in advance.
You cannot get a direct reference to a content script's DOM element from the background page, because the background page runs in the extension's process, and the content script runs in the tab's process. See also https://code.google.com/p/chromium/issues/detail?id=39507.
The document.activeElement property in the background page refers to the active element in the background page's document. As you can imagine, this value is quite useless.
If you query the state of the currently right-clicked element, bind an event in the content script. In the next example, I've chosen the contextmenu event, because context menus can also be opened through the keyboard.
This example adds a context menu option that removes the last active element from the document.
// content script
var lastElementContext;
document.addEventListener('contextmenu', function(event) {
lastElementContext = event.target;
}, true);
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (lastElementContext && lastElementContext.parentNode) {
lastElementContext.parentNode.removeChild(lastElementContext);
lastElementContext = null;
}
});
Background script:
chrome.contextMenus.create({
title: 'DESTROY!',
contexts: ['page', 'link', 'editable', 'image', 'video', 'audio'],
onclick: function(info, tab) {
chrome.tabs.sendMessage(tab.id, 'doDestroy');
}
});

closing two successive tabs from google chrome extension

I'm writing an extension for Google Chrome.
When a search page is opened on the target site, a content script is injected which sends a request to the background page to open a detailPage in a new tab. When the detailPage is opened a content script is injected which sends a request to the background page to open the messagePage in a new tab. When the messagePage is opened a content script is injected that sends a message and closes the messagePage tab. So far, so good. Focus is returned to the detailPage tab.
But how to close the detailPage? The script that was in the messagePage is gone. The script in the detailPage is idle. I suppose background has to close both the detailPage tab and the messagePage tab. I tried two successive chrome.tabs.remove commands but this code just hangs:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.cmd == "closeMessage") {
chrome.tabs.getSelected(null, function (tab) {
chrome.tabs.remove(tab.id);
chrome.tabs.getSelected(null, function (tab) {
chrome.tabs.remove(tab.id);
});
}
});
It seems to me this has to be a part of the action upon receiving the "closeMessage" cmd. But how? And if not, how?
I understand that the tab.id of the sender is returned as sender.tab.id. Can't I just access this and use it to close the detailPage?
When you create those two tabs from a background page - save their ids. Then you can easily close them later.
var detailTabId = null;
var msgTabId = null;
...
chrome.tabs.create({url: "detail.html"}, function(tab){
detailTabId = tab.id;
});
...
chrome.tabs.create({url: "message.html"}, function(tab){
msgTabId = tab.id;
});
...
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.cmd == "closeMessage") {
chrome.tabs.remove(detailTabId);
chrome.tabs.remove(msgTabId);
}
});

Chrome extension: how do I change my icon on tab focus?

I want to be able to change the icon of my extension according to what site I am currently browsing. How can I listen for changes in tab focus?
I think I've figured this one out. You need two listeners. One to sense when the tab has been changed, one to sense when it's been updated. And then they both can trigger the same function too run. Here's what would be in the background file...
function changeIcon() {
//query the information on the active tab
chrome.tabs.query({active: true}, function(tab){
//pull the url from that information
var url=tab[0].url;
//do whatever you need to do with the URL
//alert(url);
//change the icon
chrome.browserAction.setIcon({path: 'pathToIcon'});
});
}
//listen for new tab to be activated
chrome.tabs.onActivated.addListener(function(activeInfo) {
changeIcon();
});
//listen for current tab to be changed
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
changeIcon();
});
Simply register for tab update notifications in your background page:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
{
if (changeInfo.status == "loading")
{
var url = tab.url;
var iconPath = ???
chrome.pageAction.setIcon({tabId: tabId, path: iconPath});
}
});
This handler will be called whenever a tab changes location. You don't need to care which tab is currently selected because you will have defined a different icon for each tab. Still, if you want to do it - http://code.google.com/chrome/extensions/tabs.html#event-onSelectionChanged is the way to go.