I am trying to create a chrome extension that can download mp3s from hiphopdx. I have found that once you click the play button on the website it might be possible to extract the download link of the mp3. However I am stuck on getting my extension to click on the play button.
Here is an example of the page on which I am using the extension on:
http://www.hiphopdx.com/index/singles/id.16603/title.fred-the-godson-f-the-kid-daytona-back-to-school-prod-kaimbr
my manifest json
"name": "My Test",
"version": "1",
"manifest_version": 2,
"background": {
"scripts": ["popup.js"]
},
"browser_action": {
"default_icon": "icon.png"
},
"permissions": ["tabs", "http://*/*", "https://*/*"]
my popup.html
<!doctype html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js
function ShowOperationMessage(obj, evt) {
var fireOnThis = obj;
if (document.createEvent) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent(evt, true, false);
fireOnThis.dispatchEvent(evObj);
} else if (document.createEventObject) {
fireOnThis.fireEvent('on' + evt);
}
}
ShowOperationMessage(document.getElementsByClassName("playBtns medium awesome red adjust launchplayer left"),"click");
Modifying your code to content scripts code, i was able to click the button
References
Content Scripts
Background Pages
Browser Action
Added content script section to eliminate background stuff
manifest.json
{
"name": "Mouse Clicks",
"version": "0.0.1",
"manifest_version": 2,
"description": "This demonstrates how mouse clicks are tracked",
"content_scripts": [
{
"matches": ["http://www.hiphopdx.com/index/singles/id.16603/title.fred-the-godson-f-the-kid-daytona-back-to-school-prod-kaimbr"],
"js": ["myscript.js"]
}
]
}
myscript.js
document.getElementsByClassName("playBtns medium awesome red adjust launchplayer left") returns an array so used obj[0] index
function ShowOperationMessage(obj, evt) {
var fireOnThis = obj[0];
if (document.createEvent) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent(evt, true, false);
fireOnThis.dispatchEvent(evObj);
} else if (document.createEventObject) {
fireOnThis.fireEvent('on' + evt);
}
}
ShowOperationMessage(document.getElementsByClassName("playBtns medium awesome red adjust launchplayer left"), "click");
Let me know if you need more information.
Related
Before you read this, it may be related to
How can a Chrome extension get a user's permission to use user's computer's microphone?
I've added an answer below, including code and my manifest, if that helps.
I am writing a minimal Chrome Extension (using Chrome 75.0.3770.90 on MacOS 10.14.5) to implement a 'listen' button for my accessibility project. I've written an HTML version with the JavaScript which works the microphone.
However, when I lift that code into the Extension background.js file, the text-to-speech works, but not the speech-to-text. The code runs, but the flashing mic never appears in the tab.
The code which works is:
<!DOCTYPE html>
<html>
<body>
<h2>All-in-one JavaScript Example</h2>
<button onclick="myCode();">Listen</button>
<script>
window.SpeechRecognition = window.webkitSpeechRecognition
|| window.SpeechRecognition;
function myCode() {
recognition = new SpeechRecognition();
recognition.start();
recognition.onresult = function(event) {
if (event.results[0].isFinal) {
response = event.results[0][0].transcript;
synth = window.speechSynthesis;
synth.speak( new SpeechSynthesisUtterance(
"i don't understand, "+response
));
} }
alert( "all-in-one: we're done!" );
}
</script>
</body>
</html>
Minimal reproducible example:
{
"name": "myName",
"description": "Press to talk",
"version": "0.97",
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
},
"permissions": ["contentSettings","desktopCapture","*://*/*","tabCapture","tabs","tts","ttsEngine"],
"browser_action": {
"default_icon": "images/myIcon512.png",
"default_title": "Press Ctrl(Win)/Command(Mac)+Shift+ Down to speak"
},
"commands": {
"myCommand": {
"suggested_key": {
"default": "Ctrl+Shift+Down",
"mac": "Command+Shift+Down"
},
"description": "Start speaking"
}
},
"icons": {
"512": "images/myIcon512.png"
}
}
My background JavaScript is:
window.SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
function myCode() {
var recognition = new SpeechRecognition();
recognition.onresult = function(event) {
if (event.results[0].isFinal) {
var synth = window.speechSynthesis;
synth.speak( new SpeechSynthesisUtterance(
"sorry, I don't understand."
)
);
}
}
recognition.start();
alert( "extension: we're done!" );
}
chrome.commands.onCommand.addListener(function(command) {
if (command === 'myCommand')
myCode();
});
I've also noticed that the code only runs once - I can keep on clicking in the listen button, but the Extension command only runs once (putting in an alert at the beginning of the function only gets displayed the first time around)
The default on my browser is that it should ask (once) which it does on the HTML version.
Thanks, just for reading this far! I've put an answer, with code, below.
The problem I had is that the mic seems to be a background task, whereas I'm trying to interact with tab contents. I don't think this is usual, and have ended up with a generic 'matches' value (*://*/*) in my manifest (in full):
{ "name": "Enguage(TM) - Let's all talk to the Web",
"short_name" : "Enguage",
"description": "A vocal Web interface",
"version": "0.98",
"manifest_version": 2,
"content_security_policy": "script-src 'self'; object-src 'self'",
"background": {
"scripts": ["kbTx.js"],
"persistent": false
},
"content_scripts": [
{ "matches" : ["*://*/*"],
"js": ["tabRx.js", "interp.js"]
} ],
"permissions": [
"activeTab",
"contentSettings",
"desktopCapture",
"tabCapture",
"tabs",
"tts"
],
"browser_action": {
"default_icon": "images/lbolt512.png",
"default_title": "Press Ctrl(Win)/Command(Mac)+Shift+ Space and speak"
},
"commands": {
"enguage": {
"suggested_key": {
"default": "Ctrl+Shift+Space",
"mac": "Command+Shift+Space"
},
"description": "single utterance"
} },
"icons": {
"16": "images/lbolt16.png",
"48": "images/lbolt48.png",
"128": "images/lbolt128.png",
"512": "images/lbolt512.png"
} }
I think Google might not like this! Anyway, I have put in a keyboard listener in my background code (kbTx.js):
chrome.commands.onCommand.addListener(function(command) {
if (command === 'enguage') {
// find the active tab...
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
//send it a message...
chrome.tabs.sendMessage(
tabs[0].id, // index not always 0?
null, // message sent - none required?
null // response callback - none expected!
//function(response) {console.log("done" /*response.farewell*/);}
);
});
}
});
And I've put in a context script which listens for this message (tabRx.js):
window.SpeechRecognition = window.webkitSpeechRecognition ||
window.SpeechRecognition;
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
var recognition = new SpeechRecognition();
recognition.start();
recognition.continuous = false;
recognition.onresult = function(event) {
if (event.results[0].isFinal) {
window.speechSynthesis.speak(
new SpeechSynthesisUtterance(
interp( event.results[0][0].transcript )
) );
} } }
);
The message listener essentially contains the code in the allInOne.html example above.
There may be other ways of doing this, but this works and seems reasonably lightweight.
Hope this helps.
Please feel free to add comments to this, if you think I can improve my code!
Basically I am trying to create an Auto Visitor Extension for Chrome to open a website's URL after some specific time. When I open the popup everything works fine but when the popup is close nothing works. I am trying to find out a method to run that Auto Visitor Extension even when the popup is close I have read multiple questions regarding this phenomena on Stack Overflow but none of them clarifies what I am looking for.
Here is my manifest file:
manifest.json
{
"manifest_version": 2,
"name": "Auto Visitor",
"description": "This extension will visit multiple pages you saved in extension",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
"permissions": [
"activeTab",
"storage",
"tabs",
"http://*/",
"https://*/"
]
}
The background file that i want to run even when popup is close :
background.js
// this will work only when you denie the background script in manifest
chrome.runtime.onInstalled.addListener(function(details) {
var initTime = 5;
chrome.storage.local.set({"avtime": initTime}, function() {});
});
reloadMainTab();
function reloadMainTab() {
chrome.storage.local.get('avurl', function (result) {
var urlsToLoad = result.avurl;
console.log(urlsToLoad);
if(urlsToLoad==undefined){
// do nothing
}else{
var urlsArr = urlsToLoad.split(",");
chrome.storage.local.get('avtime', function (result) {
var thisTime = result.avtime;
/*
setting it to -1 because it gets incremented by 1
when it goes into getSelected method
*/
var index=-1;
setInterval(function(){
if(index < urlsArr.length-1){
chrome.tabs.getSelected(function (tab) {
// console.log('index in get selected'+index)
chrome.tabs.update(tab.id,{url: urlsArr[index]});
});
index++;
}else{
index=-1;
}
}, thisTime+"000");
});
}
});
}
any help would be really appreciated
I am trying to create a chrome extension where if user selects the item in any web page and hit Ctrl+n then that highlighted text spelling should be altered. How do i do it? I have tried using background event page functionality where DOMContentLoaded is used so I can use the listener where there is two task, one is to find the highlighted text and another is listen for the event like Ctrl+n and do the work of reversing the spelling of that highlighted text. However, when I select the text, that selected text is not displayed in console either.
I have tried the following way
{
"manifest_version": 2,
"name": "RevText",
"description": "Reverse the spelling of higlighted text",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "html/popup.html",
"default_title": "click me"
},
"permissions": [
"activeTab",
"storage"
],
"options_page": "html/options.html",
"background": {
"scripts": ["js/eventPage.js"],
"persistent": false
}
}
function init() {
textToHyperLink();
}
function textToHyperLink(event) {
console.log(event);
var text = "";
if (window.getSelection) { // when selecting the text, the highlighted/selected text is not shown in console
text = window.getSelection().toString();
// show the popup with the name of highlighted text
console.log(text);
alert(text);
} else if (document.selection) {
text = document.selection.createRange().text;
}
return text;
}
if(document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded',init);
} else {
init();
}
UPDATE
Tried content_scripts as
{
"background": {
"scripts": ["js/eventPage.js"],
"persistent": false
},
"content_scripts": [
{
"matches" : ["http://*/*", "https://*/*"],
"js" : ["js/content.js"]
}
]
}
}
function init(event) {
console.log('event', event);
alert('event');
}
document.addEventListener('keydown',init);
This way, the console does not log anything neither alert box is opened when I click on the text and hit random keys.
At a high level, I want a user to toggle the background color of a page. I need the user to do so by clicking a button on the options page. I want the background color to take effect immediately.
At a low level, I understand that I need to send a message from the options page to the content script, reading, and writing settings to chrome.storage. However, no message passing I've tried works.
I've read that, to get a message to the content script from the options page, I need the background script to act as an intermediary. I can't get that to work, either.
In order to make my example clearer, I've removed all message passing code from all the example files below.
manifest.json
{
"manifest_version": 2,
"name": "Change Background Color",
"short_name": "Change Background Color",
"author": "The Author",
"version": "1.0.0",
"version_name": "1.0",
"options_page": "options.html",
"browser_action": {
"default_title": "Change the background color of a page."
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"]
}],
"permissions": [
"background",
"unlimitedStorage",
"storage",
"tabs",
"activeTab",
"http://*/",
"https://*/",
"*://*/*",
"<all_urls>"
]
}
options.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Options</title>
</head>
<body>
<button id="toggle-background-color">Toggle Background Color</button>
<script src="options.js"></script>
</body>
</html>
options.js
var toggle = false;
function saveOptions() {
toggle = !toggle;
chrome.storage.sync.set(
{
toggleBackgroundColor: toggle
},
function () {}
);
}
function retrieveOptions() {
chrome.storage.sync.get(
{
toggleBackgroundColor: false
},
function () {}
);
}
document.addEventListener('DOMContentLoaded', retrieveOptions);
document.getElementById('toggle-background-color').addEventListener('click', saveOptions);
content.js
chrome.storage.sync.get(
{
toggleBackgroundColor: true
},
function(settings) {
if (true === settings.toggleBackgroundColor) {
document.body.style.backgroundColor = 'green';
} else {
document.body.style.backgroundColor = 'red';
}
}
);
background.js
// This file is thus far empty
You don't need to send a message. Changing the value in chrome.storage.local is sufficient. All you need to do is be listening for changes using chrome.storage.onChanged in your content script.
You could change your content script to something like:
content.js:
function updatePage(){
chrome.storage.sync.get(
{
toggleBackgroundColor: true
},
function(settings) {
if (true === settings.toggleBackgroundColor) {
document.body.style.backgroundColor = 'green';
} else {
document.body.style.backgroundColor = 'red';
}
}
);
}
chrome.storage.onChanged.addListener(updatePage);
updatePage();
Note: You could directly use the changed value that is passed to the storage.onChnaged listener. However, in this simple example, that just adds complexity when you already have code that is getting the data you need from chrome.storage.local. If you are doing more things than just changing the background color, optimizing to not redo everything may be a better solution.
I have been working on creating my first chrome extension. I have done several of the sample extensions that can be found at https://developer.chrome.com/extensions/getstarted
How do I make an extension that will return a list of the src of all of the images on an open tab in chrome?
I know the basics in javascript, so I would like to create the extension with that language. This is not like the other in that I would like to get the full url and I would like to use simple javascript instead of trying to use json which I don't know.
Here is my manifest.json file
{
"name": "Getting Started",
"description": "Get The sources of the images",
"version": "2.0",
"permissions":[
"activeTab",
"tabs"
],
"browser_action":{
"default_title": "Image Source",
"default_popup": "popup.html"
},
"content_scripts":[
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"manifest_version": 2
}
And here is my content.js file
var len = document.images.length;
var imgs = document.images;
var sources = "";
for (var i = 0; i < imgs.length; i++){
sources = sources + imgs[i].src + "<br>";
}
document.getElementById("sources").innerHTML = sources;
/*if (len > 0){
alert(len + " images were found on page");
}
else{
alert("No images were found on page");
}*/ // Used these to see if there were any images on the page
And finally my popup.html
<html>
<head>
<title>Awesome extension</title>
<script src="content.js"></script>
</head>
<body>
<p id="sources">There might be images here</p>
</body>
</html>
To get the images from the active tab when your extension is clicked you can inject your content script using chrome.tabs.executeScript instead of having a content_scripts entry in the manifest.json and use Array.prototype.map to get an array of the images' sources:
popup.html
<html>
<head>
<title>Awesome extension</title>
<script src="popup.js"></script>
</head>
<body>
<p id="sources">There might be images here</p>
</body>
</html>
popup.js
var callback = function (results) {
// ToDo: Do something with the image urls (found in results[0])
document.body.innerHTML = '';
for (var i in results[0]) {
var img = document.createElement('img');
img.src = results[0][i];
document.body.appendChild(img);
}
};
chrome.tabs.query({ // Get active tab
active: true,
currentWindow: true
}, function (tabs) {
chrome.tabs.executeScript(tabs[0].id, {
code: 'Array.prototype.map.call(document.images, function (i) { return i.src; });'
}, callback);
});
manifest.json
{
"name": "Getting Started",
"description": "Get The sources of the images",
"version": "2.0",
"permissions":[
"activeTab",
"tabs"
],
"browser_action":{
"default_title": "Image Source",
"default_popup": "popup.html"
},
"manifest_version": 2
}