I am trying to make a simple chrome extension. I'd be glad if someone can help.
Objective: When you click the button in extension popup (popup.html), the title of current webpage is displayed in div (with id 'div1').
Problem: I have searched internet for doing this and found that passing message can be used to achieve the same. So I tried my hands on it. But its not working. I want to know what went wrong.
Status:
= The extension is successfully imported in chrome.
= when extension icon is clicked, it shows proper popup.
= when button is clicked nothing happens.
= developer console shows no error.
Files:
=====================================
//manifest.json
{
"manifest_version": 2,
"name": "some_name_extension",
"version": "0.0.1",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-3.2.1.js", "content_script.js"]
}
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
=====================================
<!-- popup.html -->
<! doctype html>
<html>
<head>
<title>
</title>
<script type="text/javascript" src="popup.js">
</script>
<style>
html
{
height: 200;
width: 200;
}
</style>
</head>
<body>
<button id="btn1">
click me!
</button>
<div id="div1">
(title will be displayed here)
</div>
</body>
</html>
=====================================
//content_script.js
document.addEventListener('DOMContentLoaded', function() {
var title1=document.getElementsByTagName("title")[0].innerHTML;
chrome.extension.onMessage.addListener(
function(msg, sender, sendResponse) {
if(sender=="popup")
{
chrome.extension.sendMessage(title1,"content","1");
}
});
});
=====================================
//popup.js
document.addEventListener('DOMContentLoaded', function() {
var mainBtn = document.getElementById('btn1');
mainBtn.addEventListener('click', function() {
chrome.extension.sendMessage("button_clicked","popup","1");
});
chrome.extension.onMessage.addListener(
function(msg, sender, sendResponse) {
if(sender=="content")
{
document.getElementById("div1").innerHTML=msg;
}
}
);
});
=====================================
link to jquery script file : https://code.jquery.com/jquery-3.2.1.js
sender is an object that's set by the browser automatically, not a string that you can pass yourself. Use the devtools debugger to inspect your code and variables by setting breakpoints inside the callbacks, don't write the code blindly.
There's no need to check the sender in this case because content scripts cannot message each other anyway.
The correct method of sending a message to a content script from the popup is chrome.tabs.sendMessage with tabId as the first parameter:
chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
chrome.tabs.sendMessage(tab.id, {
action: 'setTitle',
title: title1,
});
});
To send many values at once use an object: {action: 'setTitle', title: title1} or {action: 'buttonClicked', data: 1} and so on.
chrome.extension is deprecated for messaging, use chrome.runtime
Your code doesn't use jQuery so there's no need to inject it in manifest.json
Related
I am trying to pass message from my content script to Chrome extension Popup HTML page.
The messages are rendered in the popup page only when I open dev tools. It works perfectly fine.
Here is the script:
Content JS:
chrome.runtime.sendMessage(message);
POP UP:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{ document.getElementById("text").innerHTML+="<br\>"+request;
})
I have tried another approach to which it works but then messages in the popup page doesnot append.
So i am stuck in both the approach.
Content JS:
The "message" is based on few case conditions where it keeps changing and I want to append all the values and show it in the popup page, it works fine in 1st approach ,but here appending doesnot work.Only the 1st element shows up,other responses simply overwrite it.
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.greeting === "hello")
{
sendResponse({getmessage: message});}
});
POP Up page:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response)
{
const node = document.createElement("li");
const textnode = document.createTextNode(response.farewell);
node.appendChild(textnode);
document.getElementById("MyData").appendChild(node);
});
});
I have tried the two approaches mentioned in the description but I am stuck in both approach.
The first approach needs the dev tool to be opened first and the 2nd approach doesnot append the 2nd message to the 1st one while displaying data in the pop up page.
Pop up:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response)
{
const node = document.createElement("li");
const textnode = document.createTextNode(response.farewell);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
});
});
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse)
{
document.getElementById("text").innerHTML+="<br\>"+request;
});
POPUP HTML:
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 300px;height: 100px
}
</style>
</head>
<body>
</input>
<div id="text"> </div>
<ul id="myList">
</ul>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>
Content JS:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.greeting === "hello")
{
sendResponse({farewell: "hello"});}
});
window.addEventListener('mouseup', ClickFunction);
function ClickFunction() {
const labels = document.getElementsByTagName("label");
let l=0;
for (const label of labels) {
label.addEventListener('click', function onClick()
{
txt = label.innerText;
b=this.text;
message='Field: '+txt+';';
console.log(message);
chrome.runtime.sendMessage(message);
});
}
}
Manifest:
{
"manifest_version": 3,
"name": "test1",
"version": "0.1",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["content.js"]
}
],
"permissions": [
"storage",
"activeTab",
"scripting"
],
"action": {
"default_popup": "popup.html",
}
}
I am trying to create a chrome extension which only consist of a button. When this button is clicked, it should make an alert box which contains the highlighted textarea on a page. I can't get it to work. I can make it alert a hardcoded string, but not make it alert some highlighted text / selected textarea on a page.
Here is the javascript code popup.js:
document.addEventListener('DOMContentLoaded', function() {
test.addEventListener('click', function() {
var selObj = document.getSelection();
alert(selObj);
}, false);
}, false);
manifest.json
{
"manifest_version": 2,
"name": "test ",
"description": "test",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"activeTab"
]
}
popup.html
<
!doctype html>
<html>
<head>
<title>Test</title>
<script src="popup.js"></script>
</head>
<body>
<h1>Test</h1>
<button id="test">Test</button>
</body>
</html>
You could fetch the selection by loading a script into the page using the executeScript method in the Tabs API. You may have to add the tabs permission to your manifest.json.
To execute the script you first need to fetch the tab ID, you can do that using query and querying on fetching the active tab in the current window.
document.addEventListener('DOMContentLoaded', function() {
const test = document.querySelector('#test');
test.addEventListener('click', function() {
chrome.tabs.query({ currentWindow: true, active: true }, (tabs) => {
chrome.tabs.executeScript(tabs[0].id, { code: `document.getSelection().toString()` }, (result) => {
alert(result);
});
});
});
});
I'm building a chrome dev tool extension to capture page elements and store. For now, I'm able to capture the page element by using click method in the content script which I've injected. To send the captured element from content script to background script, I used stopPropagation and preventDefault methods to disable the click event on the element.
Problem Statement: Now I would like to revert to the element's default event after selecting an element. This is where I'm stuck on how to revert back.
manifest.json:
{
"name": "My app",
"version": "0.0.1",
"description": "My app",
"manifest_version": 2,
"devtools_page": "devtools.html",
"background": {
"scripts": [
"background.js"
]
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*",
"file://*/*"
]
}
The devtools.html has devtools.js script which creates the new tab panel in chrome dev tools and loads the panel.html.
panel.html:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<button id="insertscript">Insert script</button>
<button id="clearscript">Clear Script</button>
<input type="text" id="tagName" />
<script src="panel.js"></script>
<script src="background.js"></script>
</body>
</html>
panel.js:
(function createChannel() {
var port = chrome.extension.connect({
name: "Sample Communication" //Given a Name
});
port.onMessage.addListener(function (message) {
document.querySelector('#tagName').value = message.tagName;
});
}());
function sendObjectToInspectedPage(message) {
message.tabId = chrome.devtools.inspectedWindow.tabId;
chrome.extension.sendMessage(message);
}
document.querySelector('#insertscript').addEventListener('click', function() {
sendObjectToInspectedPage({action: "script", content: "selectitem.js"});
}, false);
document.querySelector('#clearscript').addEventListener('click', function() {
sendObjectToInspectedPage({action: "clear-script", content: "clearscript.js"});
}, false);
background.js:
chrome.extension.onConnect.addListener(function (port) {
var extensionListener = function(message, sender, sendResponse) {
if (message.tabId && message.content) {
// Attach a script to inspected page
if (message.action === "script") {
chrome.tabs.executeScript(message.tabId, {file: "assets/jquery-2.0.3.js"});
chrome.tabs.executeScript(message.tabId, {file: message.content});
} else if (message.action === "clear-script") {
chrome.tabs.executeScript(message.tabId, {code: "document.removeEventListener('click', onClick);"});
}
} else {
port.postMessage(message);
}
if (message.type === "selectedElement") {
sendResponse(message);
}
};
chrome.extension.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
chrome.extension.onMessage.removeListener(extensionListener);
});
});
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
return true;
});
selectitem.js:
function onClick(evt) {
evt.stopPropagation();
evt.preventDefault();
var elem = document.elementFromPoint(evt.clientX, evt.clientY);
chrome.extension.sendMessage({
type: "selectedElement",
tagName: elem.tagName
});
}
document.addEventListener('click', onClick, true);
Now when I click on Clear script method, I wanted to remove the stopPropagation and preventDefault which I added in selectitem.js. Because the element which I've selected could be an Anchor tag or Button or can be anything which is clickable.
I don't know on how to do this.
I found the solution with the help of this script: https://github.com/oldprojects/Simple-JavaScript-DOM-Inspector/blob/master/inspector.js
Thought this might be helpful for anyone, hence adding this as an answer.
I am making a chrome extension with two buttons : Start and Stop. On click of start button the html page, should start refreshing after a particular timer, and on click of stop it should stop refreshing.
The HTML page has a table in it say with id myTable.So after every refresh, I want to have row count of this table.
To get this I did something like this :
First for pop up, I made popup.js
window.onload = function() {
document.getElementById("startbutton").onclick = function() {
chrome.extension.sendMessage({
type: "table-row-count_start"
});
}
document.getElementById("stopbutton").onclick = function() {
chrome.extension.sendMessage({
type: "table-row-count_stop"
});
}
}
In background.js
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
switch(request.type) {
case "table-row-count_start":
alert("Refershing started");
RefreshAndCount();
break;
case "table-row-count_stop":
alert("Stop Refershing");
break;
}
return true;
});
var RefreshAndCount = function(){
chrome.tabs.getSelected(null, function(tab){
chrome.tabs.sendMessage(tab.id, {type: "table-row-count"});
chrome.browserAction.setBadgeText({text: "Counting!"});
});
}
This will make call to content.js as we need to interact with DOM of HTML page. In this script I did something like this :
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
switch(message.type) {
case "table-row-count":
var x = document.getElementById("myTable").rows.length;
alert("Row count = " + x);
var Refresh = confirm("Do you want to refresh the page?");
if (Refresh)
{
setTimeout("location.reload(true);",5000);
}
break;
}
});
The script content.js is never called. I don't know why so. Please help.
Also it will be refreshing only once, how to keep refershing after fixed timer.
Here is manifest.json
{
"name": "Refresher",
"version": "0.0.1",
"manifest_version": 2,
"description" : "Refresh the site contents after a while",
"icons": { "32": "icon.jpg" },
"browser_action": {
"default_icon": { "32": "icon.jpg" },
"default_title": "Refersher",
"default_popup": "browseraction/popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"content_scripts": [{
"matches": ["http://www.w3schools.com/html/tryit.asp?filename=tryhtml_table"],
"js": ["content.js"]
}]
}
In this case you've used a deprecated chrome.tabs.getSelected which returned the wrong tab with id -1 so the message was never delivered and an error was displayed in the console.
Use chrome.tabs.query:
var RefreshAndCount = function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {type: "table-row-count"});
chrome.browserAction.setBadgeText({tabId: tabs[0].id, text: "Counting!"});
});
};
Also note how setBadgeText was used just for the specified tab.
N.B. Always, always use the debugger to check what's wrong. Thus you can stop using alert and start using console.log or inspect/watch the variables in the debugger.
I am a novice at this and am trying to make a chrome extension for showing me in the popup window the id of all elements with certain class name in the website.
I wanted to know if my implementation was the best option to resolve the matter.
Thanks for your help, and sorry for my poor english.
manifest.json
{
"name": "Test",
"version": "1.0",
"manifest_version" : 2,
"description": "",
"browser_action": {
"default_icon": "images/icon.png",
"default_popup": "popup.html"
},
"permissions": [ "tabs","http://*/*" ]
}
popup.html
<!doctype html>
<html>
<head>
<style>
body{
height: 150px;
width: 800px;
overflow: hidden;
margin: 0px;
padding: 0px;
background: white;
}
</style>
<script src="scripts/popup.js"></script>
</head>
<body>
</body>
</html>
popup.js
// Inserting javascript code
chrome.tabs.executeScript(null, {file: "scripts/content.js"});
// Sending request
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
document.write(response.farewell);
});
});
content.js
// This function gets all the id of the elements that have a class name X and
// returns them in a string separated by ",".
function getId(className) {
// I get all elements containing className
var elements = document.getElementsByClassName(className);
// Creating array with id of the elements
var idElements= new Array();
for (var i = 0; i < elements.length; i++) {
idElements[i]=elements[i].id;
}
// Concatenate all id
var list = idElements.join(" , ");
return list;
}
var result=getId("classNameTest");
// Listening for message from popup.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.greeting == "hello")
sendResponse({farewell: result});
});
Any feedback is appreciated, thanks!
U have not registrd content script file in ur manifest file...check the below link for more details...else other work seems to be fine
http://developer.chrome.com/extensions/content_scripts.html