Change of variables via popup chrome extension - javascript

I am doing a Chrome extension and I have a problem. It is supposed to click button on the page.
I want to use a variable that I can change via the popup because I don't want to go to the script all the time and change the variable. How do I do that?
I want to change the variable sku via popup.
Manifest:
{
"name": "Clicker",
"manifest_version": 2,
"version": "0.0.1",
"browser_action": {
"default_popup": "popup.html",
"default_title": "popup",
"default_icon": "icon.png"
},
"description": "Clicker",
"content_scripts": [
{
"matches": ["https://www.zalando.pl/*"],
"js": ["content.js"]
}
],
"permissions": [
"tabs", "storage" ,"activeTab", "http://*/*", "https://*/*",
"<all_urls>",
"*://*/*",
"tabs",
"storage",
"webRequest",
"webRequestBlocking",
"webNavigation",
"alarms",
"cookies"
]
}
popup.html
<html>
<body>
<h1>Esensial Scripts</h1>
<input type="text" id="sku" placeholder="Enter Sku Here"/>
<input type="submit" id="Save" value="Save"/>
</body>
</html>
content.js
var spicker = "size-picker-";
var sku = "NI112O0J9-A110075000";
//example var sku = "XXXXXXXXX-XXXXXXXXXX";
const sleep = (milliseconds) => {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}
window.addEventListener('load', function () {
sleep(1).then(() => {
document.getElementById(spicker + sku).click();
})
})

Save the name of the button to chrome storage (You'll need to add new javascript code for popup html):
window.onload = function(){
document.getElementById('Save').onclick = function(){
var value = document.getElementById('sku').value;
chrome.storage.sync.set({'myLine': value}), function() {
console.log("you saved me!!");
});
}
Add new script to popup.html:
<script src="popup.js"></script>
And check chrome storage in content.js:
var spicker = "size-picker-";
const sleep = (milliseconds) => {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}
window.addEventListener('load', function () {
chrome.storage.sync.get('myLine', function(result){
sleep(1).then(() => {
document.getElementById(spicker + result.myLine).click();
})
});
})

Related

Chrome Extension: Fetching the value of a DOM element

I'm building my first Chrome extension and my goal is to fetch the value of a DOM element from the extension popup by the click of a button. I'm basically following the exact documentation on how to send a message but keep getting:
'Error: Could not establish connection. Receiving end does not exist.'
For now, I'm not even trying to return DOM data; just trying to console.log a message triggered by the extension and returned by the content script. Any idea what the issue might be?
Here's my setup:
manifest.jst
{
"name": "Fetch Test",
"description": "Fetch data from DOM",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "popup.html"
},
"permissions": ["activeTab", "tabs", "scripting"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content_script.js"]
}
]
}
popup.html
<html>
<body>
<div class="container">
<button id="fetch-button">Fetch</button>
</div>
</body>
</html>
<script src="popup.js"></script>
popup.js
document.getElementById("fetch-button").addEventListener("click", function () {
(async () => {
const [tab] = await chrome.tabs.query({
active: true,
lastFocusedWindow: true,
});
const response = await chrome.tabs.sendMessage(tab.id, {
greeting: "hello",
});
console.log(response);
})();
});
content_script.js
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" });
});
This sample uses executeScript to get document.title.
manifest.json
{
"name": "Get document.title",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"scripting"
],
"host_permissions": [
"<all_urls>"
],
"action": {
"default_popup": "popup.html"
}
}
popup.html
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* {
font-size: x-large;
}
</style>
</head>
<body style="min-width:300px">
<div id="title"></div><br>
<script src="popup.js"></script>
</body>
</html>
popup.js
const getTitle = () => {
console.log("getTitle() = " + document.title);
return document.title;
}
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
console.log("Execute Script");
chrome.scripting.executeScript({
target: { tabId: tabs[0].id },
func: getTitle
}, (result) => {
console.log("Recv result = " + result[0].result);
document.getElementById("title").innerText = result[0].result;
});
});
You need to include the javascript files in your popup.html file like so. Does that help?
<html>
<head>
<script src="popup.js"></script>
<script src="content_script.js"></script>
</head>
<body>
<div class="container">
<button id="fetch-button">Fetch</button>
</div>
</body>
</html>
You can try to do a long-lived message passing.
popup.js
const extensionContentScriptPort = () => {
return (async function () {
const currentTabQuery = {
active: true,
currentWindow: true,
};
const currentTabId = (await chrome?.tabs?.query(currentTabQuery))?.[0].id;
return chrome?.tabs?.connect(currentTabId, {
name: 'EXTENSION_CONTENTSCRIPT',
});
})();
};
// Add Event Listener for receiving messages
extensionContentScriptPort.then(port =>
port.onMessage.addListener((extensionContentScriptMsg) => {
console.log(extensionContentScriptMsg);
});
);
// Post message to content script
document.getElementById("fetch-button").addEventListener("click", function () {
extensionContentScriptPort?.then(port => {
port.postMessage({
greeting: "hello"
})
});
});
content_script.js
chrome?.runtime?.onConnect?.addListener(function (extensionContentScriptPort) {
console.assert(extensionContentScriptPort?.name === 'EXTENSION_CONTENTSCRIPT');
extensionContentScriptPort?.onMessage?.addListener(function (
extensionContentScriptMsg,
) {
if (extensionContentScriptMsg?.greetings === "hello") {
return extensionContentScriptPort?.postMessage({
greetings_reply: "Hey, there!"
})
}
}
}

How can I make my chrome extension try autofill when I click on the icon? I've tried quite a few things and I just keep breaking it

I want to be able to click my icon and fill my form with N/A's as shown in my content.js:
chrome.runtime.onMessage.addListener(
function(sendResponse) {
try {
document.getElementById("Note_2").value = "N/A";
document.getElementById("Note_3").value = "N/A";
document.getElementById("Note_4").value = "N/A";
sendResponse({status: "Success!"});
} catch (error) {
console.log(error)
sendResponse({status: "Exception occurred!"});
}
}
);
This is my background.js:
chrome.runtime.onInstalled.addListener(async () => {
let url = chrome.runtime.getURL("welcome/hello.html");
let tab = await chrome.tabs.create({ url });
console.log(`Created tab ${tab.id}`);
});
script.js:
/* Auto fill form */
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
}, function(response) {
console.log(response.status);
});
});
});
and lastly, my manifest.json:
{
"name": "LBOT",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "welcome/background.js"
},
"action": {
"default_popup": "ext/index.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"permissions": ["storage","activeTab","declarativeContent"]
}
I've tried various combinations of
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "testScript.js"});
});
and
chrome.action.onClicked.addListener(function (tab) {
console.log("Hello")
});
am struggling to wrap my head around this. How can I modify the extension so that when I click on the icon, it populates? I'd prefer to get rid of the button/gui all together. Hope you can help.

chrome extension command passing to content script

I would like to implement a hotkey that triggers a function in my content script.
The content script (main.js) is executed on page laod from my popup.js file.
i have added the command into my manifest.json and when I add the onCommand listener to my popup.js I can console log that it gets triggered when I press my hotkey (Ctrl+Shift+K)
However I can not get it passed to my content script.
manifest.json
{
"manifest_version": 2,
"name": "Ccghjj",
"description": "hdjdjdjsjs",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "*storage", "activeTab"],
"content_scripts": [
{
"matches": ["*://"],
"css": ["style.css"],
"js": ["jquery.js", "main.js"]
}
],
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'",
"web_accessible_resources": ["toolbar.html", "style.css"],
"commands": {
"show_deals": {
"suggested_key": {
"default": "Ctrl+Shift+K"
},
"description": "Highlight Deals"
}
}
}
popup.js
function registerButtonAction(tabId, button, action) {
// clicking button will send a message to
// content script in the same tab as the popup
button.addEventListener('click', () => chrome.tabs.sendMessage(tabId, { [action]: true }));
}
function setupButtons(tabId) {
// add click actions to each 3 buttons
registerButtonAction(tabId, document.getElementById('start-btn'), 'startSearch');
registerButtonAction(tabId, document.getElementById('deals-btn'), 'startDeals');
registerButtonAction(tabId, document.getElementById('stop-btn'), 'stopSearch');
}
function injectStartSearchScript() {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
// Injects JavaScript code into a page
// chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' });
// add click handlers for buttons
setupButtons(tabs[0].id);
});
}
injectStartSearchScript();
// hotkey command listener
chrome.commands.onCommand.addListener((show_deals) => {
console.log(`Command "${show_deals}" triggered`);
// how can I get to main.js to call deals()
});
main.js (content script)
async function deals() {
// should be fired when I press my hotkey Ctrl+Shift+K
Use messages like below
popup.js
chrome.commands.onCommand.addListener((show_deals) => {
console.log(`Command "${show_deals}" triggered`);
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(tab.id, { msg: "deals"})
})
});
and in your content script
if (!window.firstTimeExecuted) {
window.firstTimeExecuted = true;
chrome.runtime.onMessage.addListener((data, sender, sendResponse) => {
if (data.msg == 'deals') {
deals()
}
});
}

Chrome Extension execute script doesn't render browser content value

All I am trying to do change the value of popup.html on the basis of Specific URL. So I am sending message to background.js when user click on change ID of H2 from popup.html render the content by using specific JavaScript file
manifest.json
{
"manifest_version": 2,
"name": "Helpfullio",
"version": "0.1",
"content_scripts": [{
"matches": [
"*://google.com/*/*",
],
"js": ["jquery-3.2.1.js"]
}],
"browser_action": {
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"]
},
"permissions": ["tabs","http://*/*", "https://*/*"]
}
popup.html
<html>
<head>
</head>
<body>
<h2 id="change">Change ___________</h2>
<script src="popup.js"></script>
</body>
</html>
popup.js
function clickHandler(e) {
chrome.runtime.sendMessage({directive: "popup-click"}, function(response) {
// this.close(); finishes processing request
});
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('change').addEventListener('click', clickHandler);
})
background.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
switch (request.directive) {
case "popup-click":
chrome.tabs.query({
'active': true, 'lastFocusedWindow': true
}, function (tabs) {
var url = tabs[0].url;
var result = url.split('/');
var hostname = result[2];
if("bitlock" == hostname){
chrome.tabs.executeScript(null, {
file: "render.js",
// allFrames: true
});
}else{
hrome.tabs.executeScript(null, {
file: "secondrender.js",
// allFrames: true
});
}
sendResponse({});
});
break;
default:
alert("Unmatched request of '" + request + "' from script to background.js from " + sender);
}
}
);;
JavaScript doesn't render the content of popup.html as it is not finding the elementID "change" . SO here how can I give reference of popup.html file in render.js file
render.js
document.getElementById("change").textContent = 'new text';

chrome.runtime.onMessage.addListener is undefined in content script

Im trying to send message to Background, and as well receive back to content script.
This is my content_script.js
init();
function init() {
function notifyBackgroundPage(event) {
chrome.runtime.sendMessage(chromeExtID, {
greeting: "Greeting from the content script"
});
}
window.addEventListener("click", notifyBackgroundPage);
// accept messages from background
// below line addListener is undefined
chrome.runtime.onMessage.addListener(function backgroundListener(request, sender, sendResponse) {
console.log("BgExt.js says: " + request);
});
}
BgExt.js
define([], function GmailExt() {
return {
start: function () {
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
console.log('inside response');
// to send back your response to the current tab
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, {farewell: response}, function (response) {
});
});
return true;
}
);
}
};
});
This GmailExt file is loaded inside all.js (while all.js is inserted in index.html)
require([
"base_host/chrome/Server",
"kernel/Kernel",
"hydra/version",
"base_host/chrome/StartupConfig",
"hydra/apps",
"dojo/_base/Deferred",
"talkto_util/common",
"dojo/i18n!base_host/nls/CommonStrings",
"base_host/chrome/BgExt",
"dojo/domReady!"
], function (Server, Kernel, version, StartupConfig, apps, Deferred, talktoUtil, nls, BgExt) {
document.getElementById("logoMessage").innerText = nls.simple_secure_text;
var host = new Server();
//if app and not extension
chrome.browserAction && chrome.browserAction.onClicked.addListener(function() {
Deferred.when(kernel.onInit(), function () {
host.appManager.showShell();
});
return true;
});
BgExt.start();
});
client_base/host/chrome/index.html
<!DOCTYPE HTML>
<html>
<head>
<!-- Background Page for Extension/app -->
<title>Flock</title>
<meta charset="UTF-8">
<!--BUILD_REPLACE_BLOCK_START-->
<!-- This block will be remove by build.
All the files from libs/common/files.txt would be prepended to dojo.js -->
<script type="text/javascript" src="../../../hydra/src/libs/common/dojoConfig.js"></script>
<script type="text/javascript" src="../../../hydra/src/libs/common/underscore.js"></script>
<script type="text/javascript" src="../../../hydra/src/libs/common/underscore-ext.js"></script>
<!--BUILD_REPLACE_BLOCK_END-->
<script type="text/javascript" src="../../../hydra/src/libs/dojotoolkit/dojo/dojo.js"></script>
<script type="text/javascript" src="all.js"></script>
</head>
<body>
</body>
</html>
Manifest.json
{
"manifest_version": 2,
"content_security_policy": "script-src 'self' 'unsafe-eval' https://j.maxmind.com https://ssl.google-analytics.com https://flock-apps.flock.co https://flock-apps.flock-staging.co https://flock-apps.flock.com https://flock-apps.flock-staging.com; object-src 'self'",
"minimum_chrome_version": "22",
"options_page": "client_base/host/chrome/static/crx_browser_actions/index.html?app=preferences",
"name": "__MSG_extName__",
"description": "__MSG_extDescription__",
"background": {
"page": "client_base/host/chrome/index.html",
"persistent": true
},
"browser_action": {
"default_popup": "/gmail_ext/popup.html"
},
"web_accessible_resources": [
"client_base/host/chrome/static/blank.gif",
"gmail_ext/icons.png",
"gmail_ext/jquery-3.2.1.min.js",
"gmail_ext/gmail.js",
"gmail_ext/content_script.js"
],
"permissions": [
"<all_urls>",
"unlimitedStorage",
"notifications",
"idle",
"background",
"tabs",
"activeTab"
],
"optional_permissions": [
"clipboardWrite"
],
"externally_connectable": {
"matches": [
"https://*.google.com/*",
"http://localhost/*",
]
},
"content_scripts": [
{
"matches": [
"*://mail.google.com/*"
],
"css": [
"/gmail_ext/content_script.css"
],
"js": [
"/gmail_ext/loader.js"
],
"run_at": "document_end"
}
],
"version": "1.0"
}
I fixed it. The Solution was since I was using loader.js to load my content script and jquery via chrome.extension.getURL('/gmail_ext/content_script.js');
And was using "content_script.js" as a web_accessible_resources only loader.js had access to chrome object.
And yes, its a Dojo project, you can see the Working Extension here : https://chrome.google.com/webstore/detail/flock-chat-for-teams-and/enfaahabcinohafeakbliimmoholjeip?hl=en
I'm using page events now as showed here : https://developer.chrome.com/extensions/content_scripts#host-page-communication
At the top of loader.js I added below:
function initPort() {
var contentScriptPort,
chromeExtID = "lddaepjihbpbfpegjhjnkffjmmoigphe";
contentScriptPort = chrome.runtime.connect(chromeExtID);
contentScriptPort.onMessage.addListener(function (message) {
// Send data back to content script received from Background.
window.postMessage({type: "FROM_BACKGROUND", emails: message}, "*");
});
window.addEventListener("message", function _postMessage(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.emails);
contentScriptPort.postMessage(event.data);
}
}, false);
}
initPort();

Categories

Resources