Reputation: 1478
I am developing an extension for personal use, which only automatically repeat some action on a website A. This is basically the flow I want to automate using Chrome extension:
Currently, my extension is using Chrome's pageAction
for the specific website I want to automate.
manifest.json
{
"manifest_version": 2,
"name": "Automater",
"version": "0.0.1",
"page_action": {
"default_title": "Click here!",
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": [
"https://www.website.com/*"
],
"js": ["jquery-3.2.1.min.js", "content.js"],
"run_at": "document_end"
}
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"permissions": [
"activeTab",
"tabs",
"declarativeContent",
"storage"
]
}
background.js
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(
activeTab.id,
{ 'message': 'click_btn' }
);
});
});
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(
undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: {
urlContains: 'www.website.com',
schemes: ['https']
},
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
chrome.windows.onCreated.addListener(function(newWindow) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(
activeTab.id,
{ 'message': 'fill_form' }
);
});
});
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === 'btn_clicked' ) {
citationsSize = request.citationsSize;
}
}
);
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
switch(request.message) {
case 'click_btn':
$("#btn_id").click();
chrome.runtime.sendMessage({
"message": 'btn_clicked'
});
break;
case 'fill_form':
console.log('start filling');
};
}
);
I am on the website. After the extension icon is clicked, $("#btn_id").click();
works and it opens a new window as a popup (this popup is opened by the website I'm currently on). I use chrome.windows.onCreated
to catch the newly opened window, but, from here, I cannot send a message fill_form
to the new window's content script.
How can I execute the script in the newly opened popup window?
Upvotes: 1
Views: 1475
Reputation: 69276
You can solve this in more than one way, but in my humble opinion you don't really need messages. If you want to execute the content script when you click the page action, then don't add it in the manifest.json
, but split it in two different files, one for clicking the button and one for filling and sending the form, then just inject them programmatically when needed using chrome.tabs.executeScript
.
The workflow would be the following:
content_click_btn.js
is loaded in the page and clicks the button.content_fill_form.js
is injected in the popup window.Your code would become something like this:
background.js
:
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: 'content_click_btn.js', runAt: 'document_end'});
});
});
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: {
urlContains: 'www.website.com',
schemes: ['https']
},
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}]);
});
});
NOTE: since January 2021, use chrome.action
instead of chrome.pageAction
and chrome.scripting.executeScript()
instead of chrome.tabs.executeScript()
.
content_click_btn.js
:
function listener(newWindow) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
if (tabs[0].url.includes('http://www.website.com')
chrome.tabs.executeScript(tabs[0].id, {file: 'content_fill_form.js', runAt: 'document_end'});
});
chrome.windows.onCreated.removeListener(listener);
}
chrome.windows.onCreated.addListener(listener);
document.getElementById('btn_id').click();
content_fill_form.js
:
console.log('Filling the form...');
// Do something to fill and send the form.
Also, you don't actually need it, but if you want to use jQuery you can just leave it in the "content_scripts"
field in your manifest.
Upvotes: 1