So, I've been in a dilemma and can't quite figure out how to properly inject a JavaScript file into YouTube with my Chrome Extension.
Now I've tried these things:
- Content Scripts with matches:
// manifest.json
"permissions": [
"scripting",
"activeTab",
"tabs",
"storage",
"notifications"
],
...
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["video.js"],
"run_at": "document_idle"
}
]
Doesn't always trigger, epically when using 'Back' and 'Forward' buttons
- Programmatically injecting using
chrome.tabs.onUpdated.addListener
:
// background.js
let tabURL
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (!changeInfo.status && tab.url != tabURL){
let url = new URL(tabURL)
if (url.hostname == 'www.youtube.com') {
if (url.pathname == '/watch') {
console.log('UPDATED');
chrome.scripting.executeScript({
target: {tabId: tabId},
files: ['video.js']
})
}
}
}
})
Works sometimes, but things like reloads don't work.
- Using a
window.addEventListener('pageshow', startup);
in video.js (content_script)
Never worked
The closest I gotten is this code:
//background.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if(!changeInfo.status){
let url = new URL(tab.url)
console.log(url);
if (url.hostname == 'www.youtube.com') {
if (url.pathname == '/watch') {
console.log('UPDATED');
chrome.scripting.executeScript({
target: {tabId: tabId},
files: ['video.js']
})
}
}
}
})
With a setTimeout in the content_script:
// video.js (content_script)
setInterval(startup(), 1000)
Almost works in all scenarios, but causes the script to fire more than once, leading to errors in console like:
Also doesn't account for other people's loading times.
The needed outcomes:
- Inject JS when content is available on YouTube (For instance: like button) also accounting for different internet speeds.
- Inject only at: https://www.youtube.com/watch
- When I click the back/forward buttons to go to other
/watch
pathnames to also inject JS. - When tab is reloaded.
What is the best way to achieve these goals? Is there any documentation that I've missed?