Chrome extension - send message from content script to the pop-up - javascript

I just wanted to ask you if it's possible to send a message from content script to the popup script. It works the other way around - from popup to content:
popup.js
let counter = 0;
let userInput = document.getElementById("userInput").addEventListener("click", () => {
counter++
let params = {
active: true,
currentWindow: true
}
chrome.tabs.query(params, gotTabs);
function gotTabs(tabs) {
chrome.tabs.sendMessage(tabs[0].id, counter)
}
});
content.js
chrome.runtime.onMessage.addListener(gotMessage);
function gotMessage(message) {
console.log(message)
}
index.html
<!DOCTYPE html>
<html>
<body>
<h2>Hello there!</h2>
<button id="userInput">Click me!</button>
</body>
<script src="popup.js"></script>
</html>
My question is, how can I send a message from content script to the popup script, if its possible, because when I switch those files, i got errors like:
content.js:14 Uncaught TypeError: Cannot read property 'query' of undefined
at HTMLDocument.myClickHandler
Thanks for your help.

Related

How to send data entered in the extension menu to another file

I'm writing an extension, I made a menu to it in which the user enters some data. It is necessary to make so that on a click on the button (in the menu of expansion) these data.
Here is how it must works: background.js is the file that is responsible for js in the extension menu. content.js is the file that is responsible for making changes to the DOM on the sites.
document.getElementById('btn').onclick = function() {
var first = document.getElementById('first').value;
var second = document.getElementById('second').value;
//sending in content.js
chrome.extension.sendMessage('hello');
}
<head>
<script type="text/javascript" src="content.js"></script>
<script type="text/javascript" src="background.js"></script>
</head>
<input type="text" id="first">
<input type="text" id="second">
<input type="button" id="btn" value="send">
content.js Getting data:
chrome.extension.onMessage.addListener(function(request){
if(request=='hello'){
console.log('1. Get: ', request);
}
});
But from background.js i get nothing.
Here is manifest.json
{
"manifest_version": 2,
"version": "1.3",
"description": "name",
"browser_action":{
"default_popup": "content/popup.html"
},
"background": {
"persistent": false,
"scripts": ["content/background.js"]
},
"content_scripts": [
{
"matches": [ "https://google.com/*" ],
"js": ["content/content.js"],
"css": ["content/qq.css"],
"run_at": "document_end"
}
]
}
It turns out that I need to send the entered data in the field with the button send to a file that will insert this data into the page I need. How to do it?
Help, because if I put the code that it does in my js file, then it tries to take this data frominput on the page, and not from the extension menu.
Here is the structure:
Ok, there seems to be a couple of n00b issues here:
background.js is a script that runs in the background of all tabs/pages. (The "background" section in the manifest.json specifies this).
PS: The way to debug the background.js is to open chrome's extension page (chrome://extensions/) and click on "Inspect Views: background page" from there. Typically, this is where most of your code would be.
content.js will automatically be inserted into all google.com pages, according to your manifest.
popup.html and it's code only exists as long as the popup is visible. It's typically very light, with little code. So, in your popup.html, remove the two existing <script> entries you have, and just use a single script, (typically popup.js):
<script type="text/javascript" src="popup.js"></script>
When sending info from the popup (or background) to the current tab (in your case it's going to be google.com only) you use the general code:
// Get the current tab & tell it to do something
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var currentTab = tabs[0];
var id = currentTab.id;
chrome.tabs.sendMessage(id,
{ action: 'foo', data:... },
response => { console.log('some response from content.js is:' + response); });
});
but to send a message to the background (from a page or your content script inside google.com), you'd just use this chrome.runtime.sendMessage({action:'foo', data:...});
So, your code should probably be something like:
popup.html
<head>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>...
popup.js:
document.getElementById('btn').onclick = function() {
var first = document.getElementById('first').value;
var second = document.getElementById('second').value;
//sending in content.js
var foo_data="I am foo";
// Get the current tab & tell it to do something
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var currentTab = tabs[0];
var id = currentTab.id;
chrome.tabs.sendMessage(id,
{ action: 'hello', foo:foo_data, first:first, second:second },
response => { console.log(response); });
});
}
background.js
(nothing)
content.js
chrome.runtime.onMessage.addListener(function(request,sender, sendResponse){
if(request.action=='hello'){
console.log(request.foo + ' ' request.first + ' ' + request.second);
sendResponse('I got foo!');
}
});
If it's any help, I've a tiny project that I use to get started on webextension projects here: https://github.com/cmroanirgo/webextension-template. It's got some code to help with making it work cross browser (Firefox, Opera & maybe Edge)
I hope this helps.

Calling JS function onClick

I am trying to call this Javascript function. When I hit my button, there is nothing loading. I set an id for my button. With the onclick I load the function onLinkedInLoad. But is it not that function I should call to activate the script? Can anybody see what I am doing wrong here?
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<button id="btn">Try Me</button>
<script type="text/javascript">
document.getElementById("btn").onclick = onLinkedInLoad;
</script>
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: myKey
authorize: true
onLoad: onLinkedInLoad
</script>
<script type="text/javascript">
// Setup an event listener to make an API call once auth is complete
function onLinkedInLoad() {
IN.Event.on(IN, "auth", shareContent);
}
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to share content on LinkedIn
function shareContent() {
// Build the JSON payload containing the content to be shared
var payload = {
"comment": "Check out developer.linkedin.com! http://linkd.in/1FC2PyG",
"visibility": {
"code": "anyone"
}
};
IN.API.Raw("/people/~/shares?format=json")
.method("POST")
.body(JSON.stringify(payload))
.result(onSuccess)
.error(onError);
}
</script>
</body>
</html>
Update:
I get this in my console:
18 Uncaught ReferenceError: onLinkedInLoad is not defined
www.linkedin.com/uas/js/userspace?v=0.0.1191-RC8.56309-1429&apiKey=myKey&authorize=true&onLoad=onLinkedInLoad&secure=1&:
22 Uncaught Error: You must specify a valid JavaScript API Domain as part of this key's configuration.
I putted my APIkey in also. I just replaced in the code here with "myKey". I also tried with .addEventListener('click', onLinkedInLoad), but still nothing happens
Try to load the function definition script before the call script. Or better, take all the scripts in another file and just load that on your HTML.
I've tried your code on js fiddle and it works by doing that.

Failing to get simple SoundCloud javascript api method to work

I have the following code below :
<!DOCTYPE html>
<html>
<head>
<script src="http://connect.soundcloud.com/sdk.js"></script>
<script>
SC.initialize({
client_id: "f520d2d8f80c87079a0dc7d90db9afa9"
});
SC.get("/users/3207",{}, function(user){
console.log("in the function w/ " + user);
});
</script>
</head>
</html>
The code should print the user name to the console however whenever I run this, my console gives the error of :
Failed to load resource: The requested URL was not found on this server:
file://api.soundcloud.com/users/3207?client_id=f520d2d8f80c87079a0dc7d90db9afa9&format=json&_status_code_map%5B302%5D=200
However if I were to directly http://api.soundcloud.com/users/3207.json?client_id=f520d2d8f80c87079a0dc7d90db9afa9, then I get a valid JSON result.
Is there something incorrect with my how I am using the SC.get function?
Thanks
Well, you should test your index.html locally on a web-server like Apache and not by opening it as a file.
Working example
SC.initialize({
client_id: "f520d2d8f80c87079a0dc7d90db9afa9"
});
SC.get("/users/3207", {}, function(user) {
console.log("in the function w/ " + JSON.stringify(user));
var res = document.getElementById("result");
res.innerHTML = JSON.stringify(user);
});
<script src="http://connect.soundcloud.com/sdk.js"></script>
<div id="result"></div>

Uncaught SyntaxError: Unexpected end of input on popup.html file in Chrome Extension

I'm making a Chrome Extension for the first time. When I right click the extension icon and inspect the popup this is the error I'm getting.
Uncaught SyntaxError: Unexpected end of input myextension/popup.html
And the fact that it's failing on an HTML file is making me confused. I looked through about 10 other similar questions and most of the time it's apparently a syntax error in the javascript file. I've linted mine with a couple different linters and still nothing is showing up. Could somebody help me spot a mistake here? It's 62 lines:
function updatePopup(){
listofbad = JSON.parse(localStorage["badguys"]);
$('#dumpster').empty();
var i = 0;
for(i = 0; i < listofbad.length; i = i+1){
$('#dumpster').append( listofbad[i] + "<br>");
}
}
$(document).ready(function(){
if(localStorage["badguys"] != undefined){
var namesthe = JSON.parse(localStorage["badguys"]);
updatePopup();
chrome.tabs.query({
active: true,
currentWindow: true
},
function(tabs) {
/* ...and send a request for the DOM info... */
console.log("Sending message from popup to content");
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', subject: 'DOMInfo', newnames: namesthe}
);
}
);
}
});
function save_options() {
var thenames = [];
if( localStorage["badguys"] != undefined ){
thenames = JSON.parse(localStorage["badguys"]);
}
console.log("JSONParse: " + thenames.toString());
//thenames = ["Aidenator", "Moobot", "Nightbot", "Teamevilmaster"];
var elname = document.getElementById("namebox").value;
if( $.inArray(elname, thenames) > -1 ){
return false;
}
thenames.push(elname);
localStorage["badguys"] = JSON.stringify(thenames);
updatePopup();
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
/* ...and send a request for the DOM info... */
console.log("Sending message from popup to content");
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', subject: 'DOMInfo', newnames: thenames}
);
});
}
document.getElementById('namebutton').addEventListener('click', save_options);
function clearlist() {
localStorage["badguys"] = [];
updatePopup();
}
document.getElementById('clearbutton').addEventListener('click', clearlist );
Here's the small HTML that goes along with it too:
<!doctype html>
<head>
<title>Extension Options</title>
<script src="jquery.js" type="text/javascript"></script>
</head>
<body>
<div id='status'></div>
Annoying person's name:
<input type='text' id="namebox"></input>
<button id="namebutton">Add</button>
<button id="clearbutton">Clear List</button>
<hr>
<center>
<i>List of Removed People:</i>
</center>
<div id="dumpster"></div>
<hr>
<center>
<img src="carlton.jpg" width="50px">
</center>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>
Maybe I've been staring at a screen too long to spot any typos, but if somebody could help me out here, that'd be great. This Chrome Extension business has been quite frustrating.

Chrome Extensions - Send messages to external page not working

I'm developing a chrome app and i'm trying to send a message to an external webpage. In the whole scenario, the external webpage needs to send a message back (but i'm not trying to achieve this yet).
Here is my code:
background.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Prototype</title>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<script src="https://code.jquery.com/jquery.js"></script>
<script src="background.js"></script>
</body>
</html>
background.js
var FileMessage = "Hello!";
var scriptName = "script.js";
var tabID;
//open a new tab with an app
function openApp() {
var url = "link_to_external_webpage_on_personal_server";
var win = window.open(url);
}
//function to run js files inside the extension
function runScript(script){
chrome.tabs.executeScript(null, {file: script});
}
//function to send a message to all tabs
function sendMessage(){
chrome.tabs.query({'active': true}, function(tabs) {
if(tabs.length === 1){
var tab = tabs[0];
//var tabID = tab.id;
chrome.extension.sendMessage(null, {newMessage : FileMessage});
console.log("extension sent a message...");
}
});
}
//main()
$(document).ready(function() {
openApp();
//when a new tab is updated
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
//createEvent();
sendMessage();
}
});
});
/*function createEvent(){
$.event.trigger({
type: "newMessage",
message: "Hello World!"
});
}*/
external js file
$(document).ready(function() {
console.log( "app script is running" );
$(document).on("newMessage", newMessageHandler);
/*document.addEventListener("myEvent",myEventHandler);*/
document.addEventListener("newMessage",myEventHandler);
document.addEventListener('newMessage', function(event) {
console.log("message received...");
}, false);
});
I can see that most of the code is running with the console prints. The only one i'm not receiving is the one saying "message received". I've also tried using events (commented in the code) but i was not successful too.
Does anyone know what i'm doing wrong ?
Thanks in advance for the help !

Categories

Resources