My js code just doesnt execute the chrome.tabs.query line. When I went through it stepwise over the debugger it will immediately go to the next executing statement ie return. I looked this up and I understand that this is an asynchronous call but even after waiting the debugger or alert inside the chrome.tabs.query just wouldn't hit. Please help.
/*
Given the name of a beast, get the URL to the corresponding image.
*/
debugger;
function beastNameToURL(beastName) {
switch (beastName) {
case "Save Session":
debugger;
chrome.tabs.query({currentWindow: true}, function(tabs) {
debugger;
alert("1");
tabs.forEach(function(tab){
unsafeWindow.console.log("helllllloooooooooooooooooo");
unsafeWindow.console.log(tab.url);
});
for (var tab of tabs) {
if (tab.active) {
console.log(tab.url);
}
}
});
return;
case "Load Session":
debugger;
return chrome.extension.getURL("beasts/snake.jpg");
case "Turtle":
return chrome.extension.getURL("beasts/turtle.jpg");
}
}
/*
Listen for clicks in the popup.
If the click is not on one of the beasts, return early.
Otherwise, the text content of the node is the name of the beast we want.
Inject the "beastify.js" content script in the active tab.
Then get the active tab and send "beastify.js" a message
containing the URL to the chosen beast's image.
*/
document.addEventListener("click", function(e) {
if (!e.target.classList.contains("btn")) {
return;
}
var chosenBeast = e.target.textContent;
var chosenBeastURL = beastNameToURL(chosenBeast);
chrome.tabs.executeScript(null, {
file: "/content_scripts/beastify.js"
});
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {beastURL: chosenBeastURL});
});
});
I have also given permissions to tabs in the manifest.
{
"manifest_version": 2,
"name": "Session",
"version": "1.0",
"description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
"icons": {
"48": "icons/beasts-48.png"
},
"applications": {
"gecko": {
"id": "beastify#mozilla.org",
"strict_min_version": "45.0"
}
},
"permissions": [
"activeTab",
"tabs"
],
"browser_action": {
"default_icon": "icons/beasts-32.png",
"default_title": "Session",
"default_popup": "popup/choose_beast.html"
},
"web_accessible_resources": [
"beasts/frog.jpg",
"beasts/turtle.jpg",
"beasts/snake.jpg"
]
}
Related
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 am trying to set a variable from a user textbox input so all my content_scripts can use it based on the amount that is set. In my case, I have a textbox input that is on my chrome extension. This textbox allows the user to input a number. In each of my content_scripts I have a random number generator function that will change based on the number user inputs in the text box. Ideally, I would like it to be without a set button. Also, I looked online mostly people are using the document.getElementById().value and assign it back to the javascript file, however, I am not getting the value from the DOM, I need to get it from popup.html. All my content_scripts are pretty much the same so I only showed one of them below. Please let me know if you want to see the others.
manifest.json
{
"manifest_version": 2,
"name": "My Page",
"description": "My Page",
"version": "1.0",
"permissions": [
"tabs",
"https://mywebpage.com/*",
"storage"
],
"browser_action": {
"default_icon": {
"30": "images/icons/30.png",
"48": "images/icons/48.png"
},
"default_popup": "popup.html"
},
"icons": {
"16": "images/icons/16.png",
"20": "images/icons/20.png",
"30": "images/icons/30.png",
"48": "images/icons/48.png",
"128": "images/icons/128.png"
}
}
popup.html
<!doctype html>
<html>
<body>
<input type="text" class="delay" name="delay" placeholder="Delay(s)">
<input type="button" value="set" onclick=" ">
<button class ="button button0" button id="clickactivity">Button</button>
<button class ="button button2" button id="clickactivity2">Button</button>
<button class ="button button5" button id="clickactivity5">Button</button>
<script src="popup.js"></script>
</body>
popup.js
function injectTheScript() {
chrome.tabs.query({active: true, currentWindow: true},
function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "content_script.js"});
});
var delay = document.getElementById('delay').value; //added
chrome.storage.local.set({'delay': delay}); //added
}
function injectTheScript2() {
chrome.tabs.query({active: true, currentWindow: true},
function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "content_script2.js"});
});
}
function injectTheScript5() {
chrome.tabs.query({active: true, currentWindow: true},
function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "content_script5.js"});
});
}
document.getElementById('clickactivity').addEventListener('click', injectTheScript);
document.getElementById('clickactivity2').addEventListener('click', injectTheScript2);
document.getElementById('clickactivity5').addEventListener('click', injectTheScript5);
content_script.js:
var delay = ""; //added
chrome.storage.local.get(delay, function(result){ //added
delay = result.delay; //added
console.log("delay is: " + result.delay) //added
});
var userInputNum = //how can I get this value from popup.html
var delayMilliSeconds = Math.floor((Math.random() * userInputNum) + 1)
function outputNumber() {
console.log ("your variable is: " + userInputNum );
}
outputNumber();
I am trying to build a simple chrome extension to get a value from a page and populate a second page after.
I'm new to chrome extensions, and I'm really only doing this to make something I have to do often simpler.
So I got the part where I open the first page, get the value I need and then I open the second page in another tab. Now I'm not sure how to populate the field.
Since I already have the value on content.js, is it possible to know when the other tab has loaded to just look for the field where i need to put that value in? Or is there another way to do it? I can't get it to work.. I also tried to listen to page loads, but I don't think that will help me, as I'm only interested in one particular page.
Manifest:
{
"manifest_version": 2,
"name": "my Extension",
"version": "1",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-3.2.1.min.js", "content.js"]
}
],
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
}
}
background.js
// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
// Send a message to the active tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
});
});
//
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "open_new_tab" ) {
chrome.tabs.create({"url": request.url},
function(tab){ alert(tab.id) });
}
}
);
chrome.tabs.onUpdated.addListener(function (tabId , info) {
if (info.status === 'complete') {
chrome.tabs.sendMessage(activeTab.id, {"message": "page_loaded"});
}
});
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "clicked_browser_action" ) {
var myUrl = "http://www.google.com";
var myValue = document.getElementById("thisId").value;
if(myValue ) {
chrome.runtime.sendMessage({
"message": "open_new_tab",
"url": myUrl,
"myValue ": myValue
});
}
}
if( request.message === "page_loaded" ) {
alert("hi");
}
});
I managed to pass a message between two files/instances, namely my popup and my background scripts, but the callback function still returns undefined, so my popup script does not receive a reply. Can somebody assist me? My code is based on the docs from Google.
Background.js
chrome.runtime.onMessage.addListener(function (sender, sendResponse) {
var resp = {'navURL': "Not set yet"};
if (sender.greeting === "GetURL") {
sendResponse(resp);
}
});
popup.js
function getURL() {
chrome.runtime.sendMessage({
greeting: "GetURL"
},
function (response) {
// RESPONSE IS UNDEFINED //
console.log(response);
alert(response.navURL);
});
}
$("input[type='checkbox']").on('change', function () {
getURL();
});
Manifest.json
{
"name": "FaceBlock",
"description": "This extention gets rid of unwanted content on Facebook like sponsored posts, adds or annoying suggestions. The content you wish to see is enlarged for a better and richer social experience.",
"version": "0.0.1",
"manifest_version": 2,
"content_scripts": [
{
"matches": [
"http://*.facebook.com/*", "https://*.facebook.com/*"],
"css": ["css/popup.css"],
"js": ["js/jquery.min.js", "js/content.js"],
"run_at": "document_end",
"all_frames": true
}],
"options_page": "options.html",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "Faceblock"
},
"permissions": [
"activeTab",
"tabs",
"https://www.facebook.com/*",
"https://ajax.googleapis.com/",
"storage"
],
"background": {
"scripts": ["js/background.js"],
"persistent": false
},
"options_ui": {
// Required.
"page": "popup.html",
// Recommended.
"chrome_style": true
// Not recommended; only provided for backwards compatibility,
// and will be unsupported in a future version of Chrome (TBD).
//"open_in_tab": true
},
"web_accessible_resources": [
"images/faceblock.jpg",
"images/seigaiha.png",
"js/popup.js",
"icon.png",
"js/options.js",
"css/popup.css",
"popup.html",
"options.html"
]
}
Thanks in advance,
Niels Vermeiren
EDIT: I now have the following with the same problem
Background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
sendResponse({msg: "Element " + sender.element + " zijn zichtbaarheid wordt nu: " + sender.checked});
return true;
});
Popup.js
function getCurrentTabUrl(callback) {
return new Promise(function (resolve, reject) {
// https://developer.chrome.com/extensions/tabs#method-query
var queryInfo = {
active: true,
currentWindow: true
};
chrome.tabs.query(queryInfo, function (tabs) {
if (callback(tabs[0].url)) {
return resolve();
} else {
return reject();
}
});
});
}
function changeFacebook(data) {
console.log(data);
chrome.runtime.sendMessage(
"changeFacebook",
data,
function (response //undefined) {
console.log(response.msg); // UNDEFINED
});
}
document.addEventListener('DOMContentLoaded', function () {
var callback = function getCurrentTab(tab) {
if (tab == "https://www.facebook.com/") {
return true;
} else {
return false;
}
}
getCurrentTabUrl(callback).then(function () {
alert('on facebook');
$('.section').hide();
}, function () {
alert('not on facebook');
});
$("input[type='checkbox']").on('change', function () {
var id = $(this).attr('id');
var check = this.checked;
var data = {
'element': id,
'checked': check
};
changeFacebook(data);
});
$('.menuItem').hide();
$('.menuItem:first').show();
jQuery('.navitem').on('click', function () {
var value = $(this).html().toLocaleLowerCase();
jQuery('.menuItem').hide();
jQuery('#' + value).show();
});
});
According to doc here:
https://developer.chrome.com/extensions/runtime#event-onMessage
In your background.js, it should be
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
...
});
Since you are missing the last argument, what you really have is this:
chrome.runtime.onMessage.addListener(function (request, sender) {
...
});
So your code pretty much renamed request => sender, sender => sendResponse.
Therefore, you are trying to invoke sender as a function. But the actual sendResponse callback function is undefined. If you inspect your background page (see tips for how), you should see the error.
Tips:
When developing chrome extension, you can Inspect views: background page in the chrome://extensions page if you have any background page running.
When your popup is opened, you can inspect the popup page just you normally do.
And you can throw debuggers wherever you want, and you will be able to play around with it.
Edit:
So I have tested your code, the issue is just missing argument as I stated above. I also noticed the doc says the first two arguments are optional (not sure what the fuzz that is). But if you change your code to as below, it will work.
Background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
var resp = {'navURL': "Not set yet"};
if (request.greeting === "GetURL") {
sendResponse(resp);
}
});
Popup.js
function getURL() {
chrome.runtime.sendMessage({
greeting: "GetURL"
},
function (response) {
console.log(response);
alert(response.navURL);
});
}
To test it
Go to the background page inspect, and paste in the background page snippet.
Go to the popup page inspect (open your popup, and right click within the popup, then choose inspect)
Paste in the popup page snippet
In the popup page inspect, call getURL()
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.