As starter in Chrome extensions i'm trying to triger my function when somebody puts his youtube video into fullscreen. I've came up with code below, but it still don't triggers the alert message.
Manifest.json
{
"name": "Ext",
"version": "0.1",
"manifest_version": 2,
"description": "Catching fullscreen.",
"icons": {"16": "icon_16.png"
},
"background": {
"scripts": ["background.js"]
},
"browser_action":{
"default_title": "Ext",
"default_icon": "icon_16.png"
},
"permissions": [
"background",
"tabs",
"http://*/*",
"https://*/*"
]
}
background.js
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementByClassName('ytp-fullscreen-button');
link.addEventListener('click', function() {
alert("Fullscreen");
});
});
Beside answering to question how to add custom listener to video going fullscreen event i would be very thankful for some tips how to improve myself in this type of apps.
Read the extensions architecture overview: background page of an extension is not related to the web page so the background page script doesn't have direct access to webpage document or events.
Use a content script and fullscreenchange event (currently, it's under a vendor prefix):
addVendorEventListener(document, 'fullscreenchange', onFullscreenChange);
function onFullscreenChange(event) {
console.log(event);
}
function addVendorEventListener(element, eventName, callback) {
var vendorName = 'on' + eventName in element ? eventName
: 'onwebkit' + eventName in element ? 'webkit' + eventName
: 'onmoz' + eventName in element ? 'moz' + eventName
: null;
if (vendorName)
element.addEventListener(vendorName, callback);
}
manifest.json:
"content_scripts": [{
"matches": ["https://www.youtube.com/*"],
"js": ["content.js"]
}],
Related
I am trying to develop a chrome extension however while trying to add an EventListener on the copy action it does not work (though supported by the browser because it is working on fiddle).
here are my different files.
manifest.json
{
"manifest_version": 2,
"name": "Bla",
"description": "bla",
"version": "1.0",
"browser_action": {
"default_icon": "camera.png",
"default_title": "bla"
},
"background": {
"page": "background.html"
},
"content_scripts" : [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["oncopy.js"]
}
],
"permissions": [
"activeTab",
"https://ajax.googleapis.com/",
"clipboardRead",
"clipboardWrite"
]
}
oncopy.js
document.addEventListener("copy", function() {
alert('copied')
}, true);
The alert never pops up.
I also tried with a similar code inside a background.js file called by background.html but didn't work either... Any ideas ?
Try this
document.addEventListener('readystatechange', function(evt) {
if (evt.target.readyState === "complete") {
document.addEventListener("copy", function() {
alert('copied')
}, true);
}
}, false);
I am looking for a simple solution to change input field value with context menu trigger.
Let's say changing to bar will be enough, I'll try to add some processing later.
This is how it should work
manifest.json:
{
"manifest_version": 2,
"background" : { "scripts": ["background.js"] },
"permissions": [ "contextMenus", "http://*/*", "https://*/*" ],
"name": "test plugin",
"version": "0.1"
}
background.js:
function getClickHandler() {
//magic here
};
chrome.contextMenus.create({
"title" : "change to 'bar'",
"type" : "normal",
"contexts" : ["editable"],
"onclick" : getClickHandler()
});
The basic idea would be
Listen to contextmenu event in content scripts and record e.target (This is needed because we don't know the actual DOM node for chrome context menu api, see Issue 39507) We could directly use document.activeElement, since input elements get focused upon click
In background page, send a message to content scripts when getClickHandler is triggered
In content scripts, replace target.value with "bar"
Sample code:
manifest.json
{
"manifest_version": 2,
"background" : { "scripts": ["background.js"] },
"permissions": [ "contextMenus", "http://*/*", "https://*/*" ],
"name": "test plugin",
"version": "0.1",
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"content.js"
],
"all_frames": true
}
]
}
content.js
chrome.runtime.onMessage.addListener(function (request) {
replaceSelectedText(document.activeElement, request.text);
});
function replaceSelectedText(elem, text) {
var start = elem.selectionStart;
var end = elem.selectionEnd;
elem.value = elem.value.slice(0, start) + text + elem.value.substr(end);
elem.selectionStart = start + text.length;
elem.selectionEnd = elem.selectionStart;
}
background.js
function getClickHandler(info, tab) {
chrome.tabs.sendMessage(tab.id, {text: "bar"});
};
chrome.contextMenus.create({
"title" : "change to 'bar'",
"type" : "normal",
"contexts" : ["editable"],
"onclick" : getClickHandler
});
Updated
As #Xan has mentioned in the comments, if you just want to update <input> field, then using input.value = xxx is ok; however if you would like to manipulate arbitrary editable element, see Is there a flexible way to modify the contents of an editable element? for more ideas.
I'm new to writing extensions (and javascript). I'd like an extension to run on a timer whenever a certain URL is opened/refreshed. Code is below. This is all I have so far from what I've found online. I'm not sure if this will run for just one tab at a time.
manifest.json
{
"manifest_version": 2,
"name": "Test Plugin",
"description": "This extension is a test.",
"version": "1.0",
"content_scripts": [
{
"matches": ["https://www.google.com/*"],
"js": ["main.js"]
}
],
"permissions": [
"activeTab"
]
}
main.js
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete' && tab.active) {
setInterval(mainF, 5000)
}
})
function mainF() {
var getTitle = document.getElementById('title');
var titleValue = getTitle.Value();
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fh = fso.OpenTextFile("test.txt", 8, false, 0);
fh.WriteLine(titleValue);
fh.Close()
}
Move your logic to the Event Page.
Content Script doesn't have access to chrome.tabs API.
And according to best practices when using event pages,
Use event filters to restrict your event notifications to the cases you care about. For example, if you listen to the tabs.onUpdated event, try using the webNavigation.onCompleted event with filters instead (the tabs API does not support filters). That way, your event page will only be loaded for events that interest you.
Code snippets would look like
manifest.json
{
"manifest_version": 2,
"name": "Test Plugin",
"description": "This extension is a test.",
"version": "1.0",
"background": {
"scripts": ["main.js"],
"persistent": false
},
"permissions": [
"webNavigation"
]
}
main.js
chrome.webNavigation.onCompleted.addListener(function(details){
console.log("Certain url with hostSuffix google.com has been loaded");
}, {url: [{hostSuffix: 'google.com'}]});
As you can see, I have a problem with onclick event in chrome extension and I need your help.
$(function jony() {
jQuery.each( jQuery('img'), function() {
jQuery(this).attr('src', 'urlimage');
});
});
chrome.browserAction.onClicked.addListener(function(tab) {
jony();
});
Manifest:
{
"manifest_version": 2,
"name": "Jonyzátor",
"description": "Change images on page to JoNy!",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_title": "Klikni na mě!"
},
"permissions": [
"activeTab",
"https://ajax.googleapis.com/"
],
"content_scripts": [ {
"js": [ "jquery.js", "jonyza.js"],
"matches": [ "http://*/*", "https://*/*"]
}]
}
The scope in which jony is defined is limited to $(); outside it's simply undefined.
function jony() {
jQuery.each( jQuery('img'), function() {
jQuery(this).attr('src', 'urlimage');
}
$(jony); // Will execute on page load
// and you can still use it here
I'm not sure it was the logic you intended - do you want it to run both at page load AND when you click?
You can't use browserAction API in content scripts. The proper place for it would be a background (or event) script, and then you can message your content script to do something.
I'd like to make a website that is not part of the chrome plugin but rather just uses some API that the plugin exposes to it. Is this possible and if so, how do I do it? I googled this question and was unable to find anything.
I'm trying to use content scripts but nothing happens. Can someone explain what's wrong here?
manifest.json
{
"manifest_version": 2,
"name": "Hello World Extension",
"description": "This extension prints hello world.",
"version": "1.0",
"background": {
"page": "background.html"
},
"browser_action": {
"default_icon": "img/icon.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://locahost:8888/*"],
"js": ["EmotivAPI.js"]
}
]
}
EmotivAPI.js
var port = chrome.runtime.connect();
console.log("Hello?");
window.addEventListener("message", function (event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
alert("recieved!");
}
}, false);
js in the webpage
window.sayHello = function () {
window.postMessage({ type: "FROM_PAGE", text: "Hello from webpage!" }, "*");
}
console.log('Emotiv extension loaded.');
}
I'm calling window.sayHello() from the console
Content Scripts can help you in this case.
The content script will be injected into a page:
"content_scripts": [
{
"matches": ["http://www.google.com/*"], // try with "http://localhost:*/*" or "http://localhost:*"
"css": ["mystyles.css"],
"js": ["content_script.js"]
}
]
If you want to inject the code only sometimes, use the permissions field instead
/* in manifest.json */
"permissions": [
"tabs", "http://*/*"
],
In you extension html file, you can then execute the script by:
chrome.tabs.executeScript(null, {file: "content_script.js"});