I have created a Chrome extension that queries for elements on some webpages that feature dynamic content loading via AJAX; -- when on some of these webpages, my content.js script triggers too early (prior to the loading of the elements I need).
As a result, I set up a listener in my background script to listen for when the page has loaded enough of the elements and then it re-injects the content.js script.
background.js:
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.type == "hats_men") {
chrome.windows.get(sender.tab.windowId, function () {
/*get user's size based on product type (ie. hat)*/
var res = findSize();
if (res == -1) {
/*do nothing since no size exists for them*/
}
else {
/*send size back to content script via messaging*/
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, { type: "res_size", size: res });
});
}
});
}
});
var oldTab;
chrome.tabs.onUpdated.addListener(
function (tabId, changeInfo, tab) {
var temp = tab.url;
/*IF: on a product page, execute script.*/
if (temp && (temp.indexOf("shop.com/shop/") > -1)) && (changeInfo.url === undefined) && (temp != oldTab)) {
chrome.tabs.executeScript(tabId, { file: "content.js" });
oldTab = tab.url;
}
});
Unfortunately, I am unable to call any functions from content.js that exist in my other js files. Is there a way to invoke them? For context, I've included the js files in question into "web_accessible_resources" and "content_scripts" in my manifest.json.
external.js:
function monk(x) {
if (x != 0) {
console.log(x);
}
}
content.js:
/*get current url*/
var cur_url = window.location.href;
/*check if user is on supported site*/
if (cur_url.indexOf("hello.com/shop/") > -1 && cur_url.indexOf("quantity=1") > -1) {
/*get relevant user data*/
chrome.storage.sync.get({ data: [] }, async function (user) {
/*call prod_res() to get item details from dynamically loaded product page*/
const res = await prod_res();
/*if the product is for men*/
if (res[1] == "man") {
/*if the product is a hat*/
if (res[0] == "hat") {
/*send message to background script that this is a mens' hat*/
chrome.runtime.sendMessage({ type: "hats_men" },
function (response) {
/*listen for user's hat size in the request/message from background script*/
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
/*log user's hat size to console*/
if(request.type == "res_size"){
monk(request.size][1]);
}
}
});
}
);
}
}
});
}
/nothing logs to console/
manifest.json:
{
"manifest_version": 2,
"name": "E-Co",
"version": "0.2",
"background": {
"scripts": [ "jquery-3.5.1.min.js", "reduce.js", "background.js" ],
"persistent": false
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"jquery-3.5.1.min.js",
"content.js",
"external.js"
]
}
],
"web_accessible_resources": [
"external.js"
],
"browser_action": {
"default_icon": "logo_active.png",
"default_popup": "popup.html",
"default_title": "E-co Pop-Up"
},
"icons": {
"16": "icon_16.png",
"48": "icon_48.png",
"128": "icon_128.png"
},
"permissions": [
"storage",
"notifications",
"tabs",
"*://*/*"
],
"content_security_policy": "script-src 'self' https://ajax.aspnetcdn.com; object-src 'self'"
}