I want to insert a js file into a webpage using chrome extension. So I wrote this code into the manifest file:
"content_scripts": [
{
"matches": ["https://apps.facebook.com/frivacy/*", "http://apps.facebook.com/frivacy/"],
"js": ["jquery.js", "catch.js"]
}
]
The problem is that it cannot insert any script into these pages. I tried with other pages, and the same code is able to insert scripts in those pages...but particularly not this one. Why ??
Can you try with a trailing * for the match pattern "http://apps.facebook.com/frivacy/*" and let me know if it still fails.
OK...solved the issue...so the thing is that facebook was putting all my codes inside an iframe....so i just changed one line chrome manifest and it was working...
in the content script section, add this:
"all_frames": true
so this inserts the javascript code into all frames and it is now working...thanks though.. :)
Related
I have a tiny chrome extension that works on google translate com
How can I make it working on all domain zones(not only .com)?
Tried the following but it doesn't seem to work.
"matches": [ "*://translate.google.*/*" ],
Error
Invalid value for 'content_scripts[0].matches[0]': Invalid host wildcard.
This is not a duplicate of Chrome extension: Run on all google domains and a specific page
I want it to work only on translate page.
"matches": [ "*://*/*" ],
"include_globs": [
"*://translate.google.*/*"
]
This part makes it working on google.com search page.
I don't need this.
Thanks to #wOxxOm
Go to http://www.google.com/supported_domains
Open console and paste the following:
copy(document.body.innerText.split(" ").map((item) => { return `*://translate${item}/*` }))
Go to your manifest file and replace matches": [] array with what you've just copied.
I'm trying to write my first chrome extension and I can't get the content script loading correctly. I would like it to load for only the home page of You Tube (ie, https://www.youtube.com/); however, I would not like it to load for any other page, for example, after a user searches (ie, https://www.youtube.com/results?search_query=programming). Here is what I have:
"content_scripts": [
{
"matches": ["*://*.youtube.com/*"],
"exclude_matches": ["*://*.youtube.com/"],
"js": ["jquery.js", "content.js"]
}
]
Using the above code, content.js doesn't load at all; however, if I take out the "exclude_matches", the content script loads on https://www.youtube.com/.
Currently your manifest includes all of the youtube pages except the main page.
The following will include only the main page:
"content_scripts": [
{
"matches": ["*://www.youtube.com/"],
"js": ["jquery.js", "content.js"]
}
]
However Youtube uses history API navigation which means that if the user first opened a video page and then navigated to the main page your content script won't be injected automatically. You will need to use chrome.webNavigation.onHistoryStateUpdated event handler with url filters:
chrome.webNavigation.onHistoryStateUpdated.addListener(
function(details) {
var tabId = details.tabId;
chrome.tabs.executeScript(tabId, {file: "jquery.js", runAt: "document_start"}, function() {
chrome.tabs.executeScript(tabId, {file: "content.js", runAt: "document_start"});
});
},
{
url: [
{urlEquals: "https://www.youtube.com/"}
]
}
);
And you'll probably need a handler to remove the effect of your content scripts when user navigates from the main page. This can be implemented as a pagehide listener in the content script or using (another) onHistoryStateUpdated listener.
Alternatively you can have your scripts on all of the youtube and then check whether current url is of the home page in the content script. This might be useful in case script injection with onHistoryStateUpdated happens too late and you see a delay between navigation and subsequent applying of content scripts.
Working on a Youtube extension and will like to bring some of it into Facebook,
I'm able to modify the Youtube iframe inside Facebook posts, but the issue is that it's modify it in every site and not only on Facebook.
So I would like to know how can I set the specific parent window please?
I hope there is a way to set it simply in the manifest file,
otherwise I can just use JS to check for location.href as in Facebook it returns:
https://s-static.ak.facebook.com/common/referer_frame.php
Currently in my manifest file:
"content_scripts": [
{
"matches": [
"*://*.facebook.com/*",
"*://*.youtube.com/embed/*"
],
"css": ["styles/facebook.css"],
"all_frames": true
}
]
You can easily find the domain of the parent frame via location.ancestorOrigins, even across different domains. E.g, use the following manifest file:
"content_scripts": [{
"matches": [
"*://*.youtube.com/embed/*"
],
"js": ["js/facebook.js"],
"all_frames": true
}],
"web_accessible_resources": ["styles/facebook.css"],
and the following JS:
// Note: parentOrigin could be `undefined` in the top-level frame.
var parentOrigin = location.ancestorOrigins[0];
if (parentOrigin === 'https://facebook.com' ||
parentOrigin === 'http://facebook.com') {
var style = document.createElement('link');
style.rel = 'stylesheet';
// NOTE: This only works because the file is declared at the
// web_accessible_resources list in manifest.json
style.href = chrome.runtime.getURL('styles/facebook.css');
(document.head || document.documentElement).appendChild(style);
}
If the YouTube video is embedded via the Iframe API, you could also try to insert the style in the frame by matching the URL. E.g., without any JavaScript, the style can be loaded in the YouTube frame using:
"content_scripts": [{
"matches": [
"*://*.youtube.com/embed/*origin=https://facebook.com/*",
"*://*.youtube.com/embed/*origin=http://facebook.com/*"
],
"css": ["styles/facebook.css"],
"all_frames": true
}]
If you inject a content script both into the iframe and the parent frame, you can (using the background page as a message "router") ask the outer script.
Of use: content scripts can learn their place in the frame hierarchy.
So, the logic would be:
Youtube content script checks its hierarchy, obtaining its "index" on the tree, and computes the index of its parent.
CS messages the background with the index of its parent, requesting a check.
Background page gets the tab ID from the message, and messages all frames in the target tab with the request and parent index.
All content scripts that receive the message check their index. If it matches the parent frame, the content script checks its URL and reports back.
The background page routes the answer back to the original content script.
Tell me if you need help with any of those steps.
I'm writing a Chrome Extension in Javascript and I want to get the current time for the playing video on youtube.com. I tried using the answer from question Getting Current YouTube Video Time , e.g.:
ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
However I do get following error: "Uncaught TypeError: Cannot read property 'getCurrentTime' of null";
What I am doing wrong? I tried different values for the ElementId - movie_player, player....
Any help is appreciated. Thanks in advance.
Cheers.
edit:
Here is my manifest:
{
"manifest_version": 2,
"name": "",
"description": "",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "basic.html"
},
"permissions": [
"tabs",
"activeTab", "http://*/*", "https://*/*"
]
}
Another thing is:
If I execute this code:
ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
In the Javascript console on a Youtube Page it works fine and returns the current time.
If, however I execute this value from the extension or the console of the extension, the first line return value null.
So, as Ben assumed below, the issue seems to be that my extension doesn't even access the Youtube page.
Any help is appreciated, so thanks in advance.
Cheers
Use the following code works for chrome extension:
video = document.getElementsByClassName('video-stream')[0];
console.log(video);
console.log(video.currentTime);
In 2020, it seems we should use: player.playerInfo.currentTime.
full code on codepen
As Ben correctly assumed, you're executing the code in the context of your background page, which is wrong.
To interact with other pages, you need to inject a content script in them. See overview of that here. You'll probably need to learn how Messaging works so you can gather data in a content script and communicate it to the background page.
To make a minimal example, you can have a file inject.js
// WARNING: This example is out of date
// For the current HTML5 player, see other answers' code snippets
ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
And in your background page script, you can inject that into the current page as follows (when the button is clicked, for instance)
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
file: 'inject.js'
});
});
Then, you'll see the result of the execution in the console of the currently open page. To report the result back, you'll need to use chrome.runtime.sendMessage
you can only use getElementById when you´r referencing to the correct page. You´r using the right id. if you´r trying to access the play form another page you can use the jquery .load() function
---------EDIT----------
in the sample they do it like so:
function getCurrentTime() {
var currentTime = player.getCurrentTime();
return roundNumber(currentTime, 3);
}
This has been bugging me and I can't figure out the solution.
"content_scripts": [
{
"matches": ["chrome-extension://_MSG_##extension_id/*"],
"js": ["contentscript.js"]
}
],
if i was to replace the "chrome-extensions://.." with a url such as http://google.com/* it will work.
I even tried fallowing the pattern on chrome develoeprs pag along with replacing extension id with the actual id.
I am basically trying to inject the content script into a local page "in the extension folder"
Sorry, but you aren't meant to be able to inject content scripts into other extensions. The docs are wrong, I have reported this issue while ago.