This question already has answers here:
How to access the webpage DOM/HTML from an extension popup or background script?
(2 answers)
Closed 7 years ago.
For some reason, jQuery doesn't work in my background.js in my Google Chrome extension.
Suppose my plugin tells me all the images on the page. I verified that it gets to the below method OK, but it stops at the jQuery loop.
First, manifest.json: note I'm including jQuery, the file exists:
{
"name": "Gallery",
"version": "0.0.1",
"manifest_version": 2,
"description": "Gallery",
"browser_action": {
"default_icon": "G.png"
},
"background": {
"persistent": true,
"scripts": ["jquery-1.11.2.min.js", "background.js"]
},
"permissions": [
"tabs", "contextMenus", "http://*/*", "https://*/*"
],
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"css": ["contentstyle.css"],
"js": ["jquery-1.11.2.min.js", "contentscript.js"]
}
],
"icons": {
"32": "G.png"
}
}
background.js uses the jQuery syntax:
chrome.browserAction.onClicked.addListener(scanImages);
function scanImages()
{
// IT GETS HERE - THIS IS OK
alert('Clicked plugin button, about to start looping thru IMG...');
// BUT STOPS HERE: JQUERY DOESN'T EXECUTE
$("img").each(function() {
alert($(this).prop("src"));
});
// ANOTHER JQUERY THAT DOESN'T WORK
alert('Page title = ' + $(document).find("title").text());
}
To access the DOM of any page you need to use content scripts as explained in the comments. Though there is another way of accessing more than one scripts in your background.js.
Add the jquery-1.11.2.min.js in your background.html file.
....
<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="background.js"></script>
....
manifest.json -->
"background": {
"page": "path/to/background.html",
"persistent": true
}
You don't have to define the scripts key also, just define your background.html page and the scripts you want in the head section of the html file. I Hope it helps.
Related
DataTables configuration example
I am trying to create a Chrome extension that uses the DataTables style (which uses Bootstrap). It appears to be working locally, but when I package it as an extension, it no longer displays any style.
The manifest file is as follows:
{
"manifest_version": 2,
"name": "Cookie",
"description": "",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"]
},
"permissions": [
"activeTab",
"tabs",
"cookies",
"history",
"storage",
"https://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css",
"https://code.jquery.com/jquery-1.11.3.min.js",
"https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js",
"\u003Call_urls\u003E"
]
}
My html file uses the following scripts and css:
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css">
<!-- refers to a table named 'test' in the body -->
<script>
$(document).ready(function() {
$('#test').DataTable();
} );
</script>
Does the content scripts field have to be added to the manifest file? If so, how exactly would that look?
Thank you.
It turns out there were two main issues:
For a Google Chrome extension, a script cannot be run in the HTML file. The solution was to create another javascript file.
The scripts (jquery and bootstrap) and css had to be local, so we created another folder and added the files to that.
So I'm in the midst of creating my first Chrome Extension (Trying)
I feel like I'm close... But I genuinely don't know what to google to get the answers I need. So I'm sorry if this is a silly question.
Essentially what I'm trying to do is on click of extension - Append HTML & CSS to body and run a jQuery function. But from the looks of it, I need to call in jQuery in the manifest? Which I think I've done and it's still not working.
My Code:
manifest.json
{
"name": "Title",
"description": "Description",
"version": "1.0",
"browser_action": {
"default_title": "Hover Title",
"default_icon": "icon.png"
},
"content_scripts": [ {
"js": [ "jquery-1.7.2.min.js", "background.js" ],
"matches": [ "http://*/*", "https://*/*"]
}],
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
(function ($) {
$('body').append("Hello");
alert("Hello");
console.log("Hello");
}(jQuery));
});
Any insight into where I'm going wrong would be massively helpful!
Thank you!!
Chrome extension architecture is simple but it doesn't mean one can write code without studying it.
There are two methods of injecting content scripts:
Unconditionally on all specified urls, in which case "content_script" key is used in the manifest and the content scripts communicate with the background page via runtime.sendMessage.
Only when some event occurs like e.g. the user clicks our toolbar icon, in which case we only need the permission to access the active tab.
So in the given case we'll attach the icon click handler and inject the code afterwards:
manifest.json:
{
"name": "Title",
"description": "Description",
"version": "1.0",
"browser_action": {
"default_title": "Icon Title",
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
},
"permissions": ["activeTab"],
"manifest_version": 2
}
background.js (this is an event page because we didn't use "persistent": true in the manifest, so be advised that the [global] variables will be lost after a few seconds of inactivity; instead you should use chrome.storage API or HTML5 localStorage/sessionStorage/and so on):
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({file: "jquery-1.7.2.min.js"}, function(result) {
chrome.tabs.executeScript({file: "content.js"}, function(result) {
});
});
});
content.js (the code runs in a sandbox so there's no need to hide global variables using IIFE)
$('body').append("Hello");
alert("Hello");
console.log("Hello");
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Port error while changing chrome extension from manifest v1 to v2
I am trying to develop an addon for a website of mine. My users will need to be able to right-click any hyperlink on any webpage and then click a link in the Chrome context menu that will take them to my website to perform an action.
My addon is done, but everytime I try to test it, the link does not appear in the Chrome context menu when a hyperlink is reght-clicked.
Here is my files:
manifest.jason
{
"manifest_version": 2,
"background_page": "background.html",
"description": "Decrypt Short URLs.",
"icons": {
"128": "icon-128.png",
"16": "icon-16.png",
"48": "icon-48.png"
},
"minimum_chrome_version": "8.0.0.0",
"name": "xxxx.xxx",
"permissions": [ "http://*/*", "https://*/*", "tabs", "contextMenus" ],
"version": "1.0"
}
background.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
function handleClick() {
return function(info, tab) {
var url = 'http://xxx.xxx/api.php?url=' + info.linkUrl + '&source=chromeextension'
// Create a new tab to the results page
chrome.tabs.create({ url: url, selected:true });
};
};
chrome.contextMenus.create({
"title" : "Decrypt this Link",
"type" : "normal",
"contexts" : ["link"],
"onclick" : handleClick()
});
</script>
</body>
I will appreciate any help.
I guess the problem is in your manifest file. You use manifest version 2, but your background page is declared as in manifest version 1.
You should try to change this part of manifest.json:
"background_page": "background.html",
on this one:
"background": {
"scripts": ["background.js"]
},
and put all of your background code to background.js
More info you can read here: background_pages
P.S. Sorry, Mr. Rob W already points on this problem in the comments to main question.
I am using the following code to access the background page function in google chrome
popup.html
function sendRequest(ea,eb)
{
console.log("Inside");
chrome.extension.sendRequest({ea:ea,eb:eb},
function(response)
{
alert(response.farewell);
});
}
background.html
<html>
<body>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
sendResponse({farewell: "goodbye"});
})
</html>
</body>
</script>
manifest.json
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"background": {
"page": "background.html"
},
"content_scripts": [
{
"matches": ["http://*/"],
"js": ["popup.js"]
}
],
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "mine.html"
},
"permissions": [
"tabs","http://*/","background"
],
"web_accessible_resources": ["loading.html","bu.png"]
}
However it does not print the alert. Can anyone tell me what i am doing wrong here?
Your HTML for background.html is extremely malformed and should be fixed;
<html>
<body>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
sendResponse({farewell: "goodbye"});
})
</script>
</body>
</html>
Tags should be closed in the reverse order of them being open to maintain a correct hierarchy. Since you had not done so, the <script> element was malformed and contained invalid syntax </html></body> so would not be executed correctly.
Since you're using version 2 of the manifest you may want to consider abstracting the contents of this script element (ignoring all HTML) to its own file (e.g. background.js) and change your manifest to the following;
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"minimum_chrome_version": "18",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["http://*/"],
"js": ["popup.js"]
}
],
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "mine.html"
},
"permissions": [
"tabs","http://*/","background"
],
"web_accessible_resources": ["loading.html","bu.png"]
}
Notice that the background property now contains an array of strings representing JavaScript files to be loaded (in the order specified) in to a dynamically generated background page.
I've also set the minimum_chrome_version property to 18 as manifest version 2 should only be used when targeting this version of Chrome and above.
Developers should now only really need to use background pages instead of scripts when they need to support older versions of Chrome.
Edit
It just clicked that you're attempting to execute embedded JavaScript within your background page. Manifest version 2 introduces Content Security Policies which prohibit the execution of inline (e.g. onclick="showDialog();" and href="javascript:void(0);") and embedded JavaScript. This is why your background.html won't work and why background.js will. You will also want to ensure your popup.html doesn't contain any embedded JavaScript. The best workaround (and generally best practice anyway) is to abstract all JavaScript into its own file (e.g. popup.js) which is referenced by the HTML file. For example;
<script src="/popup.js"></script>
I want to make a browserAction extension, with an icon and a listener on it.
I have a manifest file, and a background script, the script is the following:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null,{code:'some code here'});
});
The code works on the page, i tried it on a different way (popup and a button what fires the action). But if i try it with a browserAction onclick method, nothing happens:(
The manifest:
{
"name": "somename",
"version": "1.0",
"manifest_version": 2,
"description": "sometext",
"browser_action": {
"default_icon": "images/icon.png",
"default_title": "MyStyle"
},
"background": {
"scripts": ["js/code.js"]
},
"permissions": [
"tabs",
"https://www.examplesite.ex/*",
"http://www.examplesite.ex/*",
"http://*.ex/*"
]
}
Can anybody help me?:/
Since the original question has been solved in the comments, I'll answer the follow-up question:
"Next step to make it automatic, without any click".
This can be done easily using Content scripts. When you don't have to access global variables, the following code is sufficient. Otherwise, inject the script using the techniques as mentioned here:
js/code.js
document.title = "newtitle";
manifest.json
{
"name": "somename",
"version": "1.0",
"manifest_version": 2,
"description": "sometext",
"content_scripts": {
"js": ["js/code.js"],
"matches": [ "*://www.examplesite.ex/*", "http://*.ex/*" ]
},
"permissions": [ "*://www.examplesite.ex/*", "http://*.ex/*" ]
}