I have a web worker and I want to inject my content script into it
Currently my manifest looks like
{
"manifest_version" : 2,
"name" : "",
"description" : "",
"author" : "",
"devtools_page" : "devtools/index.html",
"content_scripts": [
{
"matches": ["<all_urls>"],
"match_about_blank" : true,
"js": ["content/index.js"],
"all_frames": true
}
]
}
and my content script looks like
console.log('Hello World')
It runs on the top level page however it does not run inside my Web Worker
Related
Within the elements tab of the browser development tools, the shadow root appears as #shadow-root (open) and it is accessible from the development console via document.getElementById('parent').shadowRoot, where the element with id of parent contains the shadow root. However, from the content script of a Chrome browser extension the same code results in null (while document.getElementById('parent') of course works as expected). Is it possible to access shadow-root from a browser extension?
TL;DR. Tried to access the shadow-root element from a browser extension in the same way that it is accessible from the developer's console. Expected it to work in a browser extension in the same way that it works in the developer's console.
manifest.json
{
"content_scripts": [ {
"exclude_globs": [ ],
"exclude_matches": [ ],
"include_globs": [
"https://*.test.com/*"
],
"js": [
"script.js",
],
"matches": ["http://*/*","https://*/*"],
"run_at": "document_idle",
//"run_at": "document_end",
"all_frames": true
} ],
"permissions": [
"cookies",
"storage",
"http://*/",
"https://*/",
"tabs",
"contextMenus",
"management",
"clipboardWrite",
],
"converted_from_user_script": false,
"description": "test",
"key": "--",
"name": "test",
"version": "1.0",
"manifest_version": 2
}
script.js
if (document.readyState == "complete" || document.readyState == "interactive") {
console.log(document.getElementById('parent').shadowRoot);
} else {
document.onreadystatechange = function () {
if (document.readyState == "complete" || document.readyState == "interactive")
{
console.log(document.getElementById('parent').shadowRoot);
}
}
}
manifest.json
{
"manifest_version": 3,
"name": "Inject Scripts",
"version": "1.0",
"content_scripts": [{
"matches": [
"*://*/*"
],
"run_at": "document_end",
"js": [
"content.js"
]
}],
"web_accessible_resources": [{
"resources": [
"every site .js"
],
"matches": []
}]
}
content.js
document.head.insertAdjacentHTML('beforeend', ˋ<script src="${chrome.runtime.getURL('every site .js')}"></script>ˋ)
every site .js
console.log('injected')
<script> was inserted to <head> successful with the src="chrome-extension://<extension ID>/every site .js" attribute but there is neither console.log output nor Error message.
I installed my extension locally by enabling "Developer mode" and "Load unpacked" in "chrome://extensions/".
Do I need to specify "permissions" in manifest.json?
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.
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();"});.
My extension is simply performing actions on pages based on user clicks; it works fine on all websites except for Gmail.
Here's my manifest file:
{
"name": "My Extension",
"version": "2.0",
"description": "description.",
"permissions": [
"tabs"
],
"icons": {
"16" : "images/icon-16.png",
"48" : "images/icon-48.png",
"128" : "images/icon-128.png"
},
"background_page": "background.html",
"options_page": "Options.html",
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["css/style.css"],
"js": ["inject.js"]
}
]
}
When I click on a web page, my inject.js normally fires an alert() -- it handles onclick events. But, on Gmail pages, it does not catch the click event.
Gmail is composed of frames. By default, content scripts are only injected at the top-level frame. Add "all_frames":true to the manifest, so that the content script is also injected in the frames.
"content_scripts": [{
"matches": ["<all_urls>"],
"css": ["css/style.css"],
"js": ["inject.js"],
"all_frames": true
}]