Reputation: 554
I'm working on some code that takes an input from a text box in a browser popup and then relays that input to the background.js in order to filter a webpage using that input.
If I hard code the filtering on background.js at the start then it works (because background.js runs once at the start), but if I put the filtering inside a function that receives the input from the text box in popup.js it doesn't work.
popup.js
$(document).ready(function(){
$('#zim').click(function(){
// Get User Input in Text Box
var author = document.getElementById('author').value;
// Pass author variable to background.js
chrome.extension.getBackgroundPage().StartFiltering(author);
});
});
background.js
function StartFiltering(person){
console.log("Starting Filtering");
console.log("person: " +person);
$( "a:contains('" + person + "')" ).closest('.post-wrapper.js_post-wrapper.wide.postlist-dense').remove();
$( ".text-upper:contains('" + person + "')" ).closest('.post-wrapper.js_post-wrapper.wide.postlist-dense').remove();
$( "a:contains('" + person + "')" ).closest('.post-wrapper.js_post-wrapper.postlist-dense').remove();
};
manifest
{
"name": "Filter",
"description": "Filter out authors on homepage",
"version": "2.0",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["jquery.js","background.js"],
"persistent": false
},
"icons": {
"128": "128.png"
},
"browser_action": {
"default_title": "Filter",
"default_icon": "filter.png",
"default_popup": "popup.html"
},
"manifest_version": 2,
"content_scripts": [
{
"js": ["jquery.js","background.js"],
"matches": [ "http://example.com/*"]
}
]
}
On background.js if I put the 3 lines of jQuery outside the function, and hard code in the "person" variable and reload the extension then it will filter the website correctly. StartFiltering definitely runs, it definitely gets the "author" input from the user, but I think because background.js is only run at the start, it doesn't know to update the file? I'm not sure! Fairly new to JS and coding in general!
Have searched around on here but I can't find anyone with the same problem! Thanks in advance for any help!
EDIT - SOLVED!
So here's how I got this working...
After ExpertSystem pointed out that I was using background.js twice I cleaned up my manifest and file system so that I had 4 files: background.js, content.js, popup.js and the manifest. In my content_scripts section of the manifest I had jquery.js and content.js instead of background.js as before.
I had popup.js send a message to background.js whenever a user entered a value in the popup text box, this was done very simply as:
popup.js
chrome.runtime.sendMessage({type: "new author", author:author});
I had background.js listen in for the message, then if the message type matched the one sent from popup.js then it would store the value of the blocked author in an array (because eventually I planned to keep a list of authors to filter), and send the array as a message:
background.js
chrome.runtime.onMessage.addListener(
function(request,sender,sendResponse) {
if(request.type == "new author") {
blocked.push(request.author)
}
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id,{filter:"author",blocked:blocked})
});
});
Then I had content.js listen in for the message:
content.js
chrome.runtime.onMessage.addListener(function(msg,sender){
if (msg.filter == "author"){
for (var i=0;i<msg.blocked.length;i++){
startFiltering(msg.blocked[i]);
}
}
});
Still needs tweaking but I have all 3 pages communicating now!
Upvotes: 3
Views: 4671
Reputation: 48211
The problem
You are using background.js
both as your background-page (actually event-page) and as your content-script. So, when you visit http://example.com/* there are in fact two separate instances of background.js
: One injected into the webpage and one in your generated background-page. (By the way, you can access your background-page at chrome://extensions/ once you enable the developer mode.)
The solution
popup.html
pass a message to the content script injected into the webpage.Example (~ untested code alert ~):
// In popup
var author = ...;
chrome.tabs.getCurrent(function(currentTab) {
chrome.tabs.sendMessage(currentTab.id, {
action: 'filter',
person: author
});
});
.
// In content script
function filter(person) {
$('a:contains(' + person + ')').
closest('.post-wrapper.js_post-wrapper.wide.postlist-dense').
remove();
...
}
chrome.runtime.onMessage.addListener(function(msg) {
if ((msg.action === 'filter') && msg.person) {
filter(msg.person);
}
});
Upvotes: 4