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.
Related
My extension doesn't run at document_start. The manifest.json:
{
"manifest_version": 3,
"name": "Lift Web Restrictions",
"description": "Simple extension that removes most ads, web restrictions, adds mods to MooMoo.io / Krunker.io / and more!",
"version": "0.0.5",
"icons": {
"16": "logo/sw16.png",
"48": "logo/sw48.png",
"128": "logo/sw128.png"
},
"permissions": [],
"host_permissions": [
"*://*/*"
],
"background": {
"service_worker": "service-worker.js"
},
"web_accessible_resources": [
{
"resources": ["modules/script.js"],
"matches": ["*://*/*"]
}
],
"content_scripts": [{
"js": [
"modules/transfer.js"
],
"matches": ["http://*/*", "https://*/*"],
"all_frames": true,
"run-at": "document_start"
}]
}
There's a console.log within modules/transfer.js, however the page's script tag beats it.
Launching egAps
index.bf049c93.js?52f6f7bb66295262766e:2 Downloading d.js...
index.bf049c93.js?52f6f7bb66295262766e:2 Loading WASM c66eb3cbd8fdc1325900.wasm
^^^^ logged before script runs
index.bf049c93.js?52f6f7bb66295262766e:2 1 dependencies left
transfer.js:1 fireAt <--- where it runs
index.bf049c93.js?52f6f7bb66295262766e:2 0 dependencies left
index.bf049c93.js?52f6f7bb66295262766e:2 Running...
index.bf049c93.js?52f6f7bb66295262766e:2
Replace run-at with run_at
Thank you wOxxOm
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'm using several constants that are shared between my content.js and popup.js. How can I put them in one file and share them between both?
This does not work, global.js contains the constants
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"background": {
"persistent": false,
"scripts": ["global.js", "background.js"]
},
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["global.js", "content.js"],
"run_at": "document_end"
}],
"browser_action": {
"default_title": "Test Extension",
"default_popup": "popup.html"
},
"permissions": [
"activeTab"
]
}
global.js
var TEST = "test"
content.js/popup.js:
console.log(TEST)
in popup.js it prints TEST is not defined
You still need to add <script type="text/javascript" src="global.js"></script> to the HTML file. I thought it was included by default when you specify it in the manifest.json
I have the following manifest to run on every page load.
The problem is that it is running only when refreshing the page.
The myscript.js will not work when I click on a link and navigate, again, only on refresh.
Why is that?
Thanks
{
"name": "BrowserActionExtension",
"version": "0.0.1",
"manifest_version": 2,
"browser_action": {
"default_title": "That's the tool tip",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": [ "<all_urls>" ],
"js": [ "myscript.js" ],
"run_at": "document_end"
}
],
"permissions": [
"tabs",
"<all_urls>"
]
}
If the page contains frames and the link on which you click does not belong to the top frame you get this behaviour.
Take a look to all_frames
This value is always false, but if you set this to true the script is injected in all frames.
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
});