Well, this code was working and now, not anymore, WHY? I'm just trying to inject code via content script. (base code)
manifest.json
{
"name": "Test",
"permissions": [
"activeTab"
],
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": [
"bower_components/jquery/dist/jquery.min.js",
]
}],
"browser_action": {
"default_icon": {
"19": "icon_19.png"
}
},
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {
file: "content_script.js"
});
});
I can suppose it's a permission bug. But, what should I add for this work ?
You have to add to your permissions the url of the page wich you want to inject your code.
If I well understand, you want to inject the code in the active tab, so you can use the activeTab permission that temporally give permission to your extension for the curent tab when the user invokes your extension (by clicking the browser action for example). You can read more about it here.
Related
I am migrating a functioning browser extension to manifest v3. The problem: I want the content script to be loaded only upon clicking on the browser extension icon. However, the script is always loaded. When I try to upload to the chrome store, I get the following message, which is what I want to avoid:
Because of the host permission, your extension may require an in-depth
review that will delay publishing.
I suspect it has something to do with the "action", but I could not figure out on how to fix this. Here is the manifest:
{
"manifest_version": 3,
"name": "__MSG_extName__",
"description": "__MSG_extDescription__",
"key": "...",
"version": "1.0.0",
"icons": { ... },
"background": {
"service_worker": "/background.js"
},
"permissions": [
"storage"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"/content.js"
]
}
],
"web_accessible_resources": [
{
"resources": [
"/assets/*",
"/options.html"
],
"matches": [
"<all_urls>"
]
}
],
"options_page": "options.html",
"action": {}
}
One last note: I assume that I need activeTab permission. But again, my problem is that I want to minimize the required permissions.
Thanks in advance!
I eventually figured it out. Basically, I had to remove the "content_scripts" section. Instead, I need to inject the content script explicitly with the action handler. I was under the wrong assumption that I could constraint the content_scripts section with the right permissions.
For this to work, I had to set activeTab and scripting permissions, here the new permissions:
"permissions": [
"storage",
"activeTab",
"scripting"
],
I already had an action handler in my service worker (background.js), which now looks like this:
chrome.action.onClicked.addListener(async (tab) => {
await chrome.scripting.executeScript({
target: { tabId: tab.id, allFrames: true },
files: ["content.js"],
});
// Do other stuff...
});
I hope this answer will help someone, somewhere!
From my experience still you can use content_scripts but you should add the permission scripting.
See my manifest json below.
{
"manifest_version": 3,
"name": "*********",
"description": "This extension will repeat the media you are playing",
"version": "1.0",
"background": {
"service_worker": "background.js"
},
"content_scripts":[
{
"matches": ["https://www.google.com/*"],
"js": ["bot.js"]
}
],
"action": {
"default_icon": "icon.png",
"default_popup": "popup/popup.html"
},
"permissions": [
"activeTab",
"storage",
"tabs",
"scripting"
]
}
I am trying to develop my first extension in google chrome and I am following this tutorial: Tutorial
Everything is working great except the 2 lines of code in content.js
The problem is that the contents of "content.js" are not correct and I am getting "undefined" in chrome console for line 2.
Can someone please help me out and let me know why this happens?
I share the contents of content.js with you in order to help me out.
content.js contents:
var firstHref = $("a[href^='http']").eq(0).attr("href");
console.log(firstHref);
manifest/json file contents:
{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "0.2",
"icons": { "128": "icon_128.png" },
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-2.1.3.min.js", "content.js"]
}
],
"browser_action": {
"default_icon": "icon.png"
},
"permissions": [
"tabs"
]
}
I guess, your content script is loading before the whole document is loaded.That's why it returned undefined.
To make sure your content scripts are inject at properly, you should define "run_at" in file manifest.json
Example:
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_end",
"all_frames": true
}
],
please check Content Scripts parameters for more details.
I am new to chrome extension development. The sample code I have is not running properly.
Requirement: Executing any jquery script(say $("body").hide();) on click of context menu button.
From the code, only jquery part is not working.
I have following files:
manifest.json
{
"manifest_version": 2,
"name": "jQuery DOM",
"version": "1",
"permissions": [
"contextMenus","tabs","activeTab"
],
"background": {
"scripts": ["jquery.min.js","sample.js"]
},
"description": "Manipulate the DOM when the page is done loading",
"browser_action": {
"name": "Manipulate DOM",
"icons": ["icon.png"],
"default_icon": "icon.png"
},
"content_scripts": [ {
"js": [ "jquery.min.js", "background.js" ],
"matches": [ "http://*/*", "https://*/*"],
"run_at": "document_end"
}]
}
background.js
$("body").append('Test');
I have icon.png in folder, and it gets loaded well.
jquery.min.js in same folder
sample.js
alert("Extension loaded");
function genericOnClick(info, tab) {
alert("Tab "+tab.id);
chrome.tabs.executeScript(tab.id, {
file: "jquery.min.js",
allFrames: true
},function(){
alert("callback");
$("body").hide();
});
alert("Completed");
$("body").hide();
}
var contexts = ["page"];
for (var i = 0; i < contexts.length; i++) {
var context = contexts[i];
var title = "Test Page menu item";
var id = chrome.contextMenus.create({"title": title, "contexts":[context],
"onclick": genericOnClick});
console.log("'" + context + "' item:" + id);
}
background.js works!
All the alerts work file, but .hide function from genericOnClick doesn't work.
Even if I move the code from sample.js to backgroud.js, it won't work.
Can you please tell me where did i go wrong ?
As I mentioned, a background script isn't allowed to interact with the DOM, (while a content script isn't allowed to use chrome.contextMenus). You need to combine both, and use message passing to tell the content script when to execute. Some other adjustments I made:
I renamed background.js and content.js so that their names now
reflect what they do, and made background.js into an event page.
I removed the browser action (the
extension would need browserAction.html or background.js would
need chrome.browserAction.onClicked.addListener to do anything
other than show the icon).
Programmatically injecting jquery means that always loading it as a
content script is unnecessary (although skipping programmatic injection allows you to omit the last three permissions).
background.js doesn't need jquery
anymore, so it isn't loaded there either.
The default executeScript
tab is the active tab, so we don't need it's id.
Here's the finished product:
manifest.json
{
"manifest_version": 2,
"name": "jQuery DOM",
"version": "1",
"permissions": [
"contextMenus", "activeTab", "tabs", "http://*/", "https://*/"
],
"background": {
"scripts": [ "background.js" ],
"persistent": false
},
"content_scripts": [ {
"js": [ "content.js" ],
"matches": [ "<all_urls>" ]
}],
"description": "Manipulate the DOM when the page is done loading"
}
background.js
function genericOnClick(info, tab) {
chrome.tabs.executeScript(null,
{"file": "jquery.min.js"},
function() {
chrome.tabs.sendMessage(tab.id,{"message":"hide"});
});
}
chrome.contextMenus.create({"title": "Test Page menu item",
"contexts":["page"],
"id":"contextId"});
chrome.contextMenus.onClicked.addListener(genericOnClick);
content.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.message == 'hide') {
$("body").hide();
}
sendResponse();
});
Your content.js is probably much larger than it is here (+1 for the SSCCE). But if it is small, another option would be to omit the content script entirely, and replace the sendMessage with chrome.tabs.executeScript(null,{code:"$('body').hide();"});.
I have written a chrome extension
The manifest file is below
{
"name": "MWE",
"version": "2.0",
"permissions": [
"activeTab"
],
"content_scripts": [
{
"matches": ["https://*/*"],
"js": ["jquery.js", "content_script.js"]
} ],
"browser_action": {
"default_icon": "icon.png",
"default_title": "Make this widget bigger"
},
"manifest_version": 2
}
The jquery file that i am using is given below
$(".dijitAccordionTitle.dijitAccordionTitle-selected").parent().siblings().css("display","none")
$('#containerDiv').show().parentsUntil('body').andSelf().siblings().hide();
$("#dijit_layout_AccordionContainer_0").height($(document).height())
I want the jquery to execute after page is loaded successfully.The first line is not executing while it runs successfully in developer tools console.
What could be the issue?
Try wrapping the code in:
document.addEventListener('DOMContentLoaded', function () {
// Your code here
});
I'm trying to write a chrome extension and cannot seem to understand how to implement the following scenario:
user is on page X
user clicks on the extension's button
something happens (specifically, user is redirected to some url)
here's the manifest.json:
{
"name": "My First Extension",
"version": "1.0",
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_title": "my title"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["myscript.js"]
}
],
"permissions": [
"tabs", "https://*/*"
]
}
and here's myscript.js:
alert('entered myscript.js..');
function doMagic()
{
alert('extension button clicked!!');
}
chrome.extension.onClicked.addListener(doMagic);
i know im missing something really obvious, but cant seem to figure it out from the docs, other sites, etc.!!
Don't use a content_script, you really only need those if have to have access to the HTML of the tab.
Use a background_page for the onClicked listener and chrome.tabs.update to redirect the page.
function doMagic(tab) {
chrome.tabs.update(tab.id, { url: 'http://www.google.com' });
}
chrome.browserAction.onClicked.addListener(doMagic);