I want to update the html in popup.html when I open it through the browser action button. The popup.js should send a message to the content script running on the current tab, and should receive a response and update the html. However the content script does not receive any message, therefore not sending a proper response.
Content.js
var text = "hello";
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
switch(message.type) {
case "getText":
sendResponse(text);
break;
}
}
);
Popup.js
chrome.tabs.getCurrent(function(tab){
chrome.tabs.sendMessage(tab.id, {type:"getText"}, function(response){
alert(response)
$("#text").text(response);
});
});
Manifest.json
{
"manifest_version": 2,
"name": "It's Just A Name",
"description": "This extension is able to",
"version": "1.0",
"permissions" : ["tabs"],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "Click here!"
},
"content_scripts": [
{
"matches": ["https://*/*"],
"js": ["jquery.min.js","content.js"]
}]
}
Popup.html
<!doctype html>
<html>
<head>
<title>Title</title>
<style>
body {
font-family: "Segoe UI", "Lucida Grande", Tahoma, sans-serif;
font-size: 100%;
}
#status {
white-space: pre;
text-overflow: ellipsis;
overflow: hidden;
max-width: 400px;
}
</style>
<script src="popup.js"></script>
</head>
<body>
<p id="text"></p>
</body>
</html>
chrome.tabs.getCurrent uses for:
Gets the tab that this script call is being made from
Your popup.js should be:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {type:"getText"}, function(response){
alert(response)
$("#text").text(response);
});
});
To add to above answer, You often want to send a msg from a popup to all tabs, so
popup:
chrome.tabs.query({}, tabs => {
tabs.forEach(tab => {
chrome.tabs.sendMessage(tab.id, msgObj);
});
});
content script:
chrome.runtime.onMessage.addListener(msgObj => {
// do something with msgObj
});
As per the latest docs you can also try the following:
popup:
(async () => {
const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
content_script:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting === "hello")
sendResponse({farewell: "goodbye"});
}
);
Message passing docs!
Related
This extension scans DOM for text with V + digits e.g. V123, V333, V1, V21321321, and if the text is hovered it will send an API request from content.js and returns data. But the data should be displayed in popup and I can't seem to set it using document.getElementById('headline').innerHTML = data because it is null. Is there a way around it?
manifest.json
{
"manifest_version": 2,
"name": "AAAAA",
"description": "AAAAA Descriptionnnnnn",
"version": "1.0",
"browser_action": {
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content.js"],
"run_at": "document_end"
}
],
"permissions": [
"*://*/*"
]
}
popup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="headline" class="headline" style="background-color: #ccc; width: 300px;">
This is a headline
</div>
</body>
</html>
content.js
const elements = document.getElementsByTagName('*')
// loop through all element
for (let x = 0; x < elements.length; x++) {
let element = elements[x]
// loop through all nodes in an element
for (let y = 0; y < element.childNodes.length; y++) {
let node = element.childNodes[y]
// if node is a text node
if (node.nodeType === 3) {
const searchText = new RegExp(/V\d+/gi)
const text = node.nodeValue
const matchFound = text.match(searchText)
if (matchFound) {
element.classList.add('serialcode')
}
}
}
}
const serials = document.getElementsByClassName('serialcode')
const url = 'https://jsonplaceholder.typicode.com/todos/1'
Array.from(serials).forEach((serial) => {
serial.addEventListener('mouseover', () => {
let getData = async () => {
const response = await fetch(url, {
method: 'get'
})
return response.json()
}
getData().then(data => {
document.getElementById('headline').innerHTML = data
console.log(data)
})
})
})
I have an issue in passing content from my background.html file to my popup.html one. Here's what I'm doing on background.js:
var pollInterval = 15000 * 60; // 15 minutes, in milliseconds
function getBandi() {
$.get('http://www.comune.cormons.go.it/index.php?id=6367&no_cache=1', function (data) {
var $data = $(data);
var $bandi = $data.find('.news-latest-container .news-latest-item').has('h3:contains("Bando")');
var itemsArray = [];
$bandi.each(function () {
itemsArray.push($(this).html());
});
chrome.runtime.sendMessage({messaggi: itemsArray}, function(response) {
console.log(response);
});
});
}
function initRequest() {
getBandi();
window.setTimeout(initRequest, pollInterval)
}
$(document).ready(function () {
initRequest();
});
here's my popup html file
<!doctype html>
<style type="text/css">
#mainPopup {
padding: 10px;
height: 200px;
width: 400px;
font-family: Helvetica, Ubuntu, Arial, sans-serif;
}
h1 {
font-size: 2em;
}
</style>
<script type="text/javascript" src="../../js/jquery/jquery.min.js"></script>
<script type="text/javascript" src="browser_action.js"></script>
<div id="mainPopup">
<h1>Bandi Disponibili a Cormons</h1>
<ul id="messaggi"></ul>
</div>
Here's my javascript for the popup:
$(document).ready(function () {
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log('sono qui?')
var $container = $('#messaggi');
var $array = request.messaggi;
$array.each(function () {
$container.append("<li/>").html($(this).html());
});
sendResponse({test: true});
});
});
It is obvious by now that I'm definitely screwing something on the usage of chrome.runtime messages. But I can't figure what exactly (it is my first and probably last chrome extension).
I have simple Chrome extension to show temperature from Json.
Background.js: how to pass response temp to ??? in popup.html????
Manifest ist OK.
manifest:
{
"name": "AlarmText",
"version": "0.0.1",
"manifest_version": 2,
"permissions": ["alarms", "http://api.openweathermap.org/data/2.5/weather?q=London"],
"icons": { "128": "icons/icon128.png",
"64": "icons/icon64.png",
"32": "icons/icon32.png" },
"browser_action": {
"default_title": "Alarm test",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": true
}
}
In popup I will show temp from URL. In div id="out", popup.html:
<!doctype html>
<html>
<head>
<title>popup</title>
<script src="popup.js"></script>
<script src="background.js"></script>
</head>
<body>
<div id="out">???</div>
<button id="checkPage">Refresh</button>
</body>
</html>
In popup.js is call alarm to get temp. popup.js:
document.addEventListener('DOMContentLoaded', function() {
var checkPageButton = document.getElementById('checkPage');
checkPageButton.addEventListener('click', function() {
chrome.runtime.sendMessage({greeting: "alert"}, function(response) {
alert("response");
document.getElementById('out').innerHTML = response.farewell;
document.getElementById('checkPage').innerHTML = response.farewell;
});
}, false);
}, false);
In background.js is problem :-) How write data to div in popup.html? Why don't work sendResponse in callback function?
background.js
function getTemp(callback) {
var xhr = new XMLHttpRequest();
xhr.open ("GET", "http://api.openweathermap.org/data/2.5/weather?q=London", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// defensive check
if (typeof callback == "function") {
// apply() sets the meaning of "this" in the callback
callback.apply(xhr);
}
}
}
// send the request *after* the event handler is defined
xhr.send();
}
//alarm
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.greeting == "alert"){
alert("alert alarm");
getTemp(function() {
responseArray = JSON.parse(this.responseText);
//#TODO how to pass response temp to <div id="out">???</div> in popup.html????
alert("response get temp: " + responseArray["main"]["temp"]);
sendResponse({farewell: "goodbye"});
});
}
}
);
Thank :-)
I can't run my Unity3D applications on my node.js server. It says "failed to download data file". I think it's because of MIME types. Here are my codes. I'm new to Javascript and Node.js, sorry for that.
Server.js:
var http = require("http");
var url = require('url');
var fs = require('fs');
var io = require('socket.io');
var five = require("johnny-five"),board, led, button;
board = new five.Board();
board.on("ready", function() {
button = new five.Button(2);
});
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
switch(path){
case '/':
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world', function(err) { response.end(); });
break;
case '/index.html':
fs.readFile(__dirname + path, function(error, data){
if (error){
response.writeHead(404);
response.write("opps this doesn't exist - 404");
}
else{
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data, function(err) { response.end(); });
}
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404", function(err) { response.end(); });
break;
}
});
server.listen(8001);
var ios = io.listen(server);
ios.listen(server);
ios.sockets.on('connection', function (socket) {
if (board.isReady) {
button.on("down",function(){
console.log("down");
socket.emit('news', { hello: 'world' });
});
socket.on('toggleLed', function(data){
led = new five.Led(13);
led.strobe(1000);
});
setInterval(function(){
socket.emit('date', {'date': new Date()});
});
socket.on('client_data', function(data){
process.stdout.write(data.letter);
});
}
});
Index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unity Web Player | UnityArduino</title>
<script type='text/javascript' src='https://ssl-webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/jquery.min.js'></script>
<script type="text/javascript">
<!--
var unityObjectUrl = "http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js";
if (document.location.protocol == 'https:')
unityObjectUrl = unityObjectUrl.replace("http://", "https://ssl-");
document.write('<script type="text\/javascript" src="' + unityObjectUrl + '"><\/script>');
-->
</script>
<script type="text/javascript">
<!--
var config = {
width: 960,
height: 600,
params: { enableDebugging:"0" }
};
var u = new UnityObject2(config);
jQuery(function() {
var $missingScreen = jQuery("#unityPlayer").find(".missing");
var $brokenScreen = jQuery("#unityPlayer").find(".broken");
$missingScreen.hide();
$brokenScreen.hide();
u.observeProgress(function (progress) {
switch(progress.pluginStatus) {
case "broken":
$brokenScreen.find("a").click(function (e) {
e.stopPropagation();
e.preventDefault();
u.installPlugin();
return false;
});
$brokenScreen.show();
break;
case "missing":
$missingScreen.find("a").click(function (e) {
e.stopPropagation();
e.preventDefault();
u.installPlugin();
return false;
});
$missingScreen.show();
break;
case "installed":
$missingScreen.remove();
break;
case "first":
break;
}
});
u.initPlugin(jQuery("#unityPlayer")[0], "ArduinoWebPlayer.unity3d");
});
-->
</script>
<style type="text/css">
<!--
body {
font-family: Helvetica, Verdana, Arial, sans-serif;
background-color: white;
color: black;
text-align: center;
}
a:link, a:visited {
color: #000;
}
a:active, a:hover {
color: #666;
}
p.header {
font-size: small;
}
p.header span {
font-weight: bold;
}
p.footer {
font-size: x-small;
}
div.content {
margin: auto;
width: 960px;
}
div.broken,
div.missing {
margin: auto;
position: relative;
top: 50%;
width: 193px;
}
div.broken a,
div.missing a {
height: 63px;
position: relative;
top: -31px;
}
div.broken img,
div.missing img {
border-width: 0px;
}
div.broken {
display: none;
}
div#unityPlayer {
cursor: default;
height: 600px;
width: 960px;
}
-->
</style>
</head>
<body>
<p class="header"><span>Unity Web Player | </span>UnityArduino</p>
<div class="content">
<div id="unityPlayer">
<div class="missing">
<a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now!">
<img alt="Unity Web Player. Install now!" src="http://webplayer.unity3d.com/installation/getunity.png" width="193" height="63" />
</a>
</div>
<div class="broken">
<a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now! Restart your browser after install.">
<img alt="Unity Web Player. Install now! Restart your browser after install." src="http://webplayer.unity3d.com/installation/getunityrestart.png" width="193" height="63" />
</a>
</div>
</div>
</div>
<p class="footer">« created with Unity »</p>
</body>
</html>
Thank you for your help.
I found that it is because of this server code.
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
switch(path){
case '/':
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world', function(err) { response.end(); });
break;
case '/index.html':
fs.readFile(__dirname + path, function(error, data){
if (error){
response.writeHead(404);
response.write("opps this doesn't exist - 404");
}
else{
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data, function(err) { response.end(); });
}
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404", function(err) { response.end(); });
break;
}
});
I followed this code and found the solution.
https://github.com/jwanga/node-static-http-server
I am trying to send a message from a button click even on my website which is opened in a tab by chrome extension.
But, I'm not able to get any message from the webpage and I get a port error.
My content.js:
var port = chrome.extension.connect();
port.onMessage.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);
}
}, false);
chrome.tabs.onMessage.addListener(function(tabId, changeInfo, tab) {
alert(changeInfo);
});
Popup.js
$("#linkify").click(function() {
chrome.tabs.create({
'url': 'http://localhost:3000/signin'
}, function(tab) {
// Tab opened.
chrome.tabs.executeScript(tab.id, {
file: "jquery.js"
}, function() {
console.log('all injected');
chrome.tabs.executeScript(tab.id, {
file: "content.js"
}, function() {
console.log('all injected');
chrome.tabs.sendMessage(tab.id, function() {
console.log('all injected');
});
});
});
});
//getlink();
});
});
function checkUserAuth() {
console.log(localStorage.getItem("apiKey"));
if (localStorage.getItem("apiKey") != null) {
document.getElementById('openBackgroundWindow').style.visibility = 'hidden';
}
}
var port = chrome.extension.connect({
name: "Sample Communication"
});
port.postMessage("Hi BackGround");
port.onMessage.addListener(function(msg) {
console.log("message recieved" + msg);
});
My background.js
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
});
Script that sends message from the web url:
document.getElementById("theButton").addEventListener("click", function() {
console.log("message being sent");
window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
}, false);
Where am I going wrong here that I am not receiving any message?
After making some changes to your scripts i got it running :)
This question covers message passing from extension page -- > background, content page -- > background, extension page --> content page
Output from destination page (In my case it is http://www.google.co.in/ for you it is http://localhost:3000/signin)
Output from popup.js
Output from background.js
I have added a connection listener for var port = chrome.extension.connect({name: "Sample Communication"}); code in your popup.js in background.js it solved problem of Receiving end do not exist
background.js
chrome.extension.onConnect.addListener(function(port) {
port.onMessage.addListener(function(content) {
console.log("Connected ..." + content);
});
});
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
});
Eliminated script injection right at the time of new tab creation and injected script after tab status is complete by looking for tabs.onUpdated Listener
popup.js
flag = false;
function customFunction() {
chrome.tabs.create({
'url': 'http://www.google.co.in/'
}, function(tab) {
flag = true;
// Tab opened.
});
}
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (flag) {
if (changeInfo.status === 'complete') {
console.log("Inject is called");
injectScript(tab);
}
}
});
function injectScript(tab) {
chrome.tabs.executeScript(tab.id, {
file: "jquery.js",
"runAt": "document_start"
}, function() {
console.log('all injected');
chrome.tabs.executeScript(tab.id, {
file: "content.js",
"runAt": "document_start"
}, function() {
console.log('all injected');
chrome.tabs.sendMessage(tab.id, function() {
console.log('all injected');
});
});
});
}
window.onload = function() {
document.getElementById("linkify").onclick = customFunction;
};
var port = chrome.extension.connect({
name: "Sample Communication"
});
port.postMessage("Hi BackGround");
port.onMessage.addListener(function(msg) {
console.log("message recieved" + msg);
});
Eliminated window.postMessage() from web page and injected a custom script to send message to popup.js on click of button(Here i have chosen google logo)
content.js
function bindFunction() {
console.log("message being sent");
chrome.extension.sendMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" });
}
window.onload = function() {
document.getElementById("hplogo").onclick = bindFunction;
};
Sample Page where linkify button is similar to login button
popup.html
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
<button id="linkify">Linkify</button>
</body>
</html>
Ensured all code has permissions in manifest.json for injected script files,tabs etc in a complete manifest.json file
manifest.json
{
"name": "Complex Calls",
"description": "Complex Calls Demo",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": "screen.png"
},
"permissions": [
"tabs", "<all_urls>"
],
"version": "1"
}