Trigger chrome.browserAction.onClicked with a function

I want to trigger the click, to which following code is listening:

chrome.browserAction.onClicked.addListener(function(tab) {});

The reason is that I have a working extension, which is listening in a background-script (the addListener above) and executes some scripts on click:

chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {file: 'abc.js'});
chrome.tabs.executeScript(tab.id, {file: 'xxx.js'});
});

And now I want to trigger this "onClicked" from a context-menu:

var myContextPage = chrome.contextMenus.create({"title": myTitle, "contexts":["page"],
                                     "onclick": fctContext});

So, I thought, that the easiest way would be to have "click" in fctContext. Maybe there is a better way, but I don't how to solve my problem. I also tried to run "executeScript" but this isn't working neither.

Thanks in advance!

//Update

Solution from answers: This solution is working:

//Shared code. When the argument length is two, it is coming from the context
// menu, while a single argument is coming from the browser action.
function fctContext() {
   var tab = arguments.length == 2 ? arguments[1] : arguments[0];
   // Do whatever you want with the tab.
}

// Browser Action
chrome.browserAction.onClicked.addListener(fctContext);

// Context Menu
chrome.contextMenus.create({
   title: myTitle,
   contexts: ['page'],
   onclick: fctContext
});

Solution after testing some other things:

function fctStart() {
  chrome.tabs.getSelected(null, function(tab){ 
    chrome.tabs.executeScript(tab.id, {file: 'abc.js'});
    chrome.tabs.executeScript(tab.id, {file: 'xxx.js'});
  }); 
}

In this case, fctStart() is working from any point without having to pass the tab.

Answers:

Answer

Remember that arguments are optional in JavaScript. Each function has an associated arguments object. That arguments acts as an array. In your case, one of them requires that while the other doesn't. Having N arguments is the same in one function (Browser Action) than having M arguments in the other (Context Menu), the only difference between these two arguments is the arguments.callee which provides a way to reference the actual code within the function itself. You don't have to worry about that if you want something basic.

Your fctContext could be the share-able code between your browserAction click and your context menu. I did something similar in the Reload All Tabs extension.

Search for this.reload in https://github.com/mohamedmansour/reload-all-tabs-extension/blob/master/js/reload_controller.js, you will notice that this.reload is being used for the Context Menu and the Browser Action. You just share the code.

UPDATED with the arguments example baked in:

In your case, you do the exact same thing.

// Shared code. When the argument length is two, it is coming from the context
// menu, while a single argument is coming from the browser action.
function fctContext() {
   var tab = arguments.length == 2 ? arguments[1] : arguments[0];
   // Do whatever you want with the tab.
}

// Browser Action
chrome.browserAction.onClicked.addListener(fctContext);

// Context Menu
chrome.contextMenus.create({
   title: myTitle,
   contexts: ['page'],
   onclick: fctContext
});

The problem with the above approach is maintainability, if the API changes it might break. Personally, I would rather explicitly name the arguments. So the user doesn't have to do a lookup in the arguments array.

function fctContext(tab) {
   // Do whatever you want with the tab.
}

// Browser Action
chrome.browserAction.onClicked.addListener(fctContext);

// Context Menu
chrome.contextMenus.create({
   title: myTitle,
   contexts: ['page'],
   onclick: function (detail, tab) { fctContext(tab) }
});

Hope that helps!

Answer

In your particular example you don't need to pass tab.id as it would default to the current page anyway:

function fctContext() {
    chrome.tabs.executeScript(null, {file: 'abc.js'});
    chrome.tabs.executeScript(null, {file: 'xxx.js'});
}

If you do need the tab then:

function fctContext(tab) {
    chrome.tabs.executeScript(tab.id, {file: 'abc.js'});
    chrome.tabs.executeScript(tab.id, {file: 'xxx.js'});
}

chrome.browserAction.onClicked.addListener(fctContext);

chrome.contextMenus.create({"title": myTitle, "contexts":["page"], "onclick": function(info, tab) {
    fctContext(tab);
}});

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.