Chrome Extension multiple Matches - javascript

I want to activate some Scripts on twitch.tv with a chrome extension.
So I got a file called script2.js and a file called script3.js
In my manifest, I want to say www.twitch.tv is loaded script2.js has to be loaded, and if www.twitch.tv/directory is loaded, script3.js has to be loaded:
{
"content_scripts": [{
"js": [ "script2.js" ],
"matches": [ "*://*.twitch.tv/" ]
}, {
"js": [ "script3.js" ],
"matches": [ "*://*.twitch.tv/directory" ]
} ],
"description": "desc",
"manifest_version": 2,
"name": "TwitchTV",
"permissions": [ "*://*.twitch.tv/*" ],
"version": "1.0"
}
script2 is loaded, but script3 not. Am I doing something wrong?
EDIT:
Well with looking into the manifest I mentioned, the manifest is right.
I added an alert("test"); on top of my script and the alert is triggerd, so the script is executed correctly. But:
I add some new Buttons onto the site. And if I copy&paste my script3.js to the chrome-console on twitch.com/directory, the new buttons will be shown. But if the script is executed by chrome the buttons are not there.
Why could this be, that the script seems to be correct (because if i load it manually it works) but if its loaded automatically its wrong?

Reverse the two rules, because the first will always match
{
"js": [ "script3.js" ],
"matches": [ "*://*.twitch.tv/directory" ]
},
{
"js": [ "script2.js" ],
"matches": [ "*://*.twitch.tv/" ]
}]

Related

Injecting a script tag from a content script to an iframe with data URI src throws a 'web_accessible_resources' error even tho it's set correctly

I'm working on an extension that injects a piece of code into iframes.
I'm using manifest v3 and I have a content script that injects a script tag with my code into the iframes.
The issue comes when we have an iframe with src set as data URI like so:
<iframe src="data:text/html;base64,PHNjcmlwd...3NjcmlwdD4="></iframe>
When the content script injects the custom script tag, unlike all other possible ways to create an iframe element, this one throws an error saying the script tag is not included in the "web_accessible_resources" even tho it is. (otherwise, all other iframes would fail as well)
Error: Denying load of chrome-extension://obfggkijinagdggiiigfpppiaoielnjo/src/dest/payload-min.js. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
I believe this is a chrome bug but I'm asking for an alternative way to achieve my goal before contacting the chrome dev group.
manifest.json:
{
"name": "My Extension",
"version": "1.0",
"manifest_version": 3,
"incognito": "spanning",
"background": {
"service_worker": "background.js"
},
"permissions": [
"browsingData",
"windows",
"activeTab",
"tabs",
"webNavigation",
"webRequest",
"declarativeNetRequest",
"declarativeNetRequestWithHostAccess",
"declarativeNetRequestFeedback"
],
"host_permissions": [ "*://*/*" ],
"content_scripts": [
{
"all_frames" : true,
"run_at" : "document_start",
"match_about_blank" : true,
"match_origin_as_fallback": true,
"matches": ["*://*/*"],
"js": ["./content-script.js"]
}
],
"web_accessible_resources": [
{
"resources": [ "/src/dest/payload-min.js" ],
"matches": [ "<all_urls>" ]
}
]
}
content-script.js:
var script = document.createElement('script')
script.setAttribute('class', 'myScriptClass')
script.src = chrome.runtime.getURL('/src/dest/payload-min.js')
;(document.head||document.documentElement).appendChild(script)

Manifest.json : What is wrong with this file? [duplicate]

This is my first attempt writing a Chrome extension. I added "web_accessible_resources": ["images/icon.png"] to manifest.json because I wanted to access the image from content script. After adding this line, I got the error "Invalid value for 'web_accessible_resources[0]'.
Could not load manifest." I have checked to make sure the file path is correct, where else could I be wrong?
Any help is appreciated.
{
"name": "Bookmark Checker",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"bookmarks",
"activeTab"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches":["https://www.google.com/search?*"],
"js": ["content/content.js"]
}
],
...
"web_accessible_resources": ["images/icon.png"]
}
The syntax for web_accessible_resources in Manifest V3 has changed:
"web_accessible_resources": [{
"resources": ["/images/icon.png"],
"matches": ["<all_urls>"]
}]
The matches key must specify where to expose these resources since Chrome 89.

How to run background.js only on specific links?

I'm trying to write a chrome extension that closes tabs when they're loaded if their links contain specific words / strings. My intention was to solve that using the matches statement in the manifest.json. Unfortuantely this doesn't work. My manifest.json looks like this:
{
"manifest_version": 2,
"name": "Chrome Extension",
"version": "0.1",
"permissions": [
"tabs"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["content.js"]
}
],
"background": {
"matches": [
"https://www.google.de/",
"https://sghm.eu/iserv/login"
],
"scripts": ["background.js"],
"persistent": true
}
}
And my background.js like this:
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
console.log('background running');
chrome.tabs.remove(tabId, function() { });
}
})
In my opinion I've expressed clearly that the script only runs on google and sghm.eu, so why does it run on every loaded page?
Problems:
The "background" section can't have "matches" as you can see in the documentation. The background script runs in a separate hidden background page that's not related to tabs.
The content script declared in your manifest.json runs on all URLs. For the task you want to achieve you don't need a content script at all.
Solution consists of several steps:
Remove "content_scripts" section
Remove "matches" from "background" section
Switch to an event page script by specifying "persistent": false
Add "webNavigation" permission in manifest.json and use it to detect URL navigation.
background.js:
chrome.webNavigation.onCompleted.addListener(closeTab, {
url: [
{urlPrefix: 'https://www.google.de/'},
{urlPrefix: 'https://sghm.eu/iserv/login'},
]
});
function closeTab(e) {
if (!e.frameId) {
chrome.tabs.remove(e.tabId);
}
}

Chrome extension: Javascript content script does not have access to HTML elements

I've looked at some similar threads in SO but I couldn't understand the solutions.
Here is my code:
manifest.json
{
"name": "Test 5",
"version": "1.0.0",
"manifest_version": 2,
"permissions": [
"storage",
"tabs",
"http://*/*"
],
"web_accessible_resources": ["jquery-2.0.3.min.map"],
"content_scripts": [
{
"matches": [
"*://*.google.es/*"
],
"js": ["jquery.js", "content_scripts.js"],
"run_at": "document_end",
"all_frames": true
}
]
}
content_scripts.js
var doFilter = function() {
var classR = document.getElementsByClassName("rc");
console.log("2");
console.log("classR: "+classR.length );
//...etc
}
$(window).load(function() {
console.log("1");
doFilter(document.body);
});
The code is already loaded as a Chrome unpacked extension. I'm using Dev Tools in Chrome to debug it from the local files in my PC.
When having Dev Tools opened in the same tab as the web browser, I browse to "www.google.es" and I search for some keyword.
Then I'm able to see in Dev Tools console logs. The problem is that the last one shows that classR has length 0.
As you can see, there are elements by class name "rc", so it seems
document.getElementsByClassName("rc")
is actually not accessing to the loaded HTML document.
What am I missing here?
Thanks.

Keyboard bindings in Chrome Extension content script with GMail

I'm creating a Chrome extension that uses key bindings (i.e. will use javascript keydown and keyup event handlers) via a content script. I've hit upon a snag while trying to get this to work with GMail, though.
The the handler function in the following code (content script) seems to trigger only when I chat with someone via GChat:
$(window).bind('keydown', function(e){console.log('yay!');});
Unfortunately, it doesn't seem to activate anywhere else, including when I am trying to send an email. I looked into the GMail webpage source, and it turns out all of the content actually displayed resides in an iFrame with id canvas_frame, so I tried this:
$('#canvas_frame').content().live('keydown', function(e){console.log('yay!');});
and this:
$('#canvas_frame').content().find('body').live('keydown', function(e){
console.log('yay!');
});
Unfortunately, that didn't work either.
My manifest.json looks like this:
{
"name": "extension",
"version": "1.0",
"description": "description",
"background_page": "background.html",
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"css": [],
"js": [
"main.js"
]
}
],
"all_frames": true,
"permissions": [
"http://*/*", "https://*/*"
]
}
I was wondering if anyone had a clue about what was going on, what's the right way to do this with GMail, and if $('#canvas_frame').content().live(...) is the right way to go about it.
Thanks!
Your all_frames parameter is misplaced in manifest, it should be:
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"all_frames": true,
"js": ["main.js"]
}
],
I would approach this problem by injecting content scripts into iframes themselves and doing all key bindings there. Identify URLs of those iframes and inject individual content scripts into each of them. For example:
"content_scripts": [
{
"matches": ["http://gmail.com/*"],
"all_frames": false,
"js": ["main.js"]
},
{
"matches": ["http://gmail.com/iframe1.html"],
"all_frames": true,
"js": ["iframe1.js"]
},
{
"matches": ["http://gmail.com/iframe2.html"],
"all_frames": true,
"js": ["iframe2.js"]
}
],

Categories

Resources