So I am trying to find something on a new tab that I open from my chrome extension. The extension can open the tab but the Function runs before the script. I want a script or this function to run once the tab has loaded.
This is my manifest.json file:
{
"name": "SwagBot",
"version": "0.0.1",
"manifest_version": 2,
"description": "The Offical SwagBot extension to cop your supreme!",
"browser_action":{
"default_popup":"popup.html"
},
"permissions": [
"https://*/*",
"http://*/*",
"storage",
"tabs",
"activeTab",
"webRequest",
"webRequestBlocking",
"webNavigation",
"declarativeContent"
]
}
Here is my javascript:
function findItem(){
allText = document.getElementsByClassName("name-link");
console.log('start');
for(i = 0; i < allText.length; i++){
if(i % 2 == 0){
names.push(allText[i].innerHTML);
}else{
colors.push(allText[i].innerHTML);
links.push(allText[i].href);
}
}
for(i = 0; i < names.length; i++){
if(names[i].indexOf(itemName) != -1){
name_flag = true;
console.log('here');
}
if(colors[i].indexOf(itemColor) != -1 && name_flag == true){
itemlink = links[i];
console.log(itemlink);
}
}
}
StartButton.addEventListener('click', function() {
chrome.storage.sync.get(["category",], function(items) {
index_url = "http://www.TEHWEBPAGEIWANT.com" + items.category;
console.log(index_url);
chrome.tabs.create({
url: index_url
});
});
chrome.tabs.onCreated.addListener(findItem);
});
});
Any help would really be appreciated, thank you. :)
Related
I inherited the a extension that is used internally on Chromebooks to pass authentication to a web server for the currently logged in user. The extension itself works fine as is right now with manifest V2 but we are trying prepare for manifest v3 and are having issues getting the extension to fire.
Here is an example of the extension as it is currently setup.
Manifest File
{
"background": {
"scripts": [ "background.min.js" ]
},
"description": "User Agent",
"icons": {
"128": "icon.png",
"16": "icon.png"
},
"manifest_version": 2,
"name": "User Agent",
"permissions": [ "background", "identity", "identity.email", "http://*/", "https://*/" ],
"version": "1.0.3"
}
Background File
(function() {
var e = void 0,
n = new Event("userInfoChanged"),
t = 0,
a = function() {
chrome.identity.getProfileUserInfo(function(a) {
var o = !1;
o = (new Date).getTime() > t + 179e4 || e != a.email, e = a.email, o && (n.username = e, document.dispatchEvent(n))
})
};
document.addEventListener("userInfoChanged", function(e) {
t = (new Date).getTime();
var n = new XMLHttpRequest;
n.open("GET", "URL_TO_WEB_SERVER" + encodeURIComponent(btoa(e.username)), !0), n.send()
}, !1), setInterval(a, 6e4), a(), setInterval(function() {
n.username = e, document.dispatchEvent(n)
}, 18e5)
}).call(this);
From what I have read to update this you need to move from "background page" to using a "service worker"
We need to the authentication that is happening in the current background.min.js file to happen on boot / extension install. I have been reading and it looks as though using the chrome.alarms is the way to go.
I have updated the manifest file
Updated Manifest File
{
"background": {
"service_worker": "background.min.js"
},
"description": "User Agent",
"icons": {
"128": "icon.png",
"16": "icon.png"
},
"manifest_version": 3,
"name": "User Agent",
"permissions": ["alarms", "background", "identity", "identity.email", "http://*/",
"https://*/" ],
"version": "1.2.0"
}
and updated the background.min.js file
Updated Background File
chrome.alarms.onAlarm.addListener(a => {
console.log('Alarm! Alarm!', a);
});
chrome.runtime.onInstalled.addListener(() => {
chrome.alarms.get('alarm', a => {
if (!a) {
chrome.alarms.create('alarm', {periodInMinutes: 1});
}
});
});
(function() {
var e = void 0,
n = new Event("userInfoChanged"),
t = 0,
a = function() {
chrome.identity.getProfileUserInfo(function(a) {
var o = !1;
o = (new Date).getTime() > t + 179e4 || e != a.email, e = a.email, o && (n.username = e, document.dispatchEvent(n))
})
};
document.addEventListener("userInfoChanged", function(e) {
t = (new Date).getTime();
var n = new XMLHttpRequest;
n.open("GET", "URL_TO_WEB_SERVER" + encodeURIComponent(btoa(e.username)), !0), n.send()
}, !1), setInterval(a, 6e4), a(), setInterval(function() {
n.username = e, document.dispatchEvent(n)
}, 18e5)
}).call(this);
I am able to get the extension to install but it appears that the function in the background script is not running. I am a more of a systems guy and am more comfortable with PowerShell. This fell in my lap but I am very interested in figuring this out. Any help would be appreciated.
I also wrote to Reddit , but it seems that it is not reflected
Add alarms to permissions in manifest.json
Write alarm registration function and activation process in your background.js
const ALARM_NAME = "alarmName";
// Alarm registration function
function addTimer(): void {
chrome.alarms.create(ALARM_NAME, {
periodInMinutes: 15,
});
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === ALARM_NAME) {
periodicFunctionYouLike();
}
});
}
// Register if there is no alarm with the specified name
chrome.alarms.get(ALARM_NAME)
.then((alarm) => {
if (!alarm) {
addTimer();
}
}).catch(() => {
addTimer();
});
In this process, Google Drive synchronization is actually realized on a regular basis with our chrome extension.
I'm migrating an extension from manifest v2 to manifest v3 (and refactor and redesign...)
In the old version we were using an iframe within the tab, like this:
background.js
const open = () => {
const oldIframe = document.getElementById('cm-frame');
if (oldIframe) {
oldIframe.remove();
return;
}
const iframe = document.createElement('iframe');
iframe.setAttribute('id', 'cm-frame');
iframe.setAttribute('style', 'top: 10px;right: 10px;width: 450px;height: 100%;z-index: 2147483650;border: none; position:fixed;');
iframe.setAttribute('allow', '');
iframe.src = chrome.extension.getURL('index.html');
iframe.frameBorder = 0;
document.body.appendChild(iframe);
};
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.executeScript({
code: '(' + open.toString() + ')();'
}, () => { });
});
I've tried the same approach using chrome.actions.onClicked.addListener with chrome.scripting.executeScript and had no luck.
I know we could just use a popup ("default_popup": "popup.html",) but the iframe works better in terms of integration and design.
I was able to make it work.
background.js
chrome.action.onClicked.addListener(async function (tab) {
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: () => {
const oldIframe = document.getElementById('cm-frame');
if (oldIframe) {
oldIframe.remove();
return;
}
const iframe = document.createElement('iframe');
iframe.setAttribute('id', 'cm-frame');
iframe.setAttribute(
'style',
'top: 10px;right: 10px;width: 400px;height: calc(100% - 20px);z-index: 2147483650;border: none; position:fixed;'
);
iframe.setAttribute('allow', '');
iframe.src = chrome.runtime.getURL('popup.html');
document.body.appendChild(iframe);
},
});
});
This my manifest.json file in case someone also needs it (I had to add stuff to permissions and web_accessible_resources to make it work and load correctly):
{
"manifest_version": 3,
"name": "Contact Mapping Extension",
"background": { "service_worker": "background.bundle.js" },
"action": {
"default_icon": "icon-34.png"
},
"icons": {
"128": "icon-128.png"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "<all_urls>"],
"js": ["contentScript.bundle.js"],
"css": ["content.styles.css"]
}
],
"web_accessible_resources": [
{
"resources": ["content.styles.css", "icon-128.png", "icon-34.png", "popup.html"],
"matches": ["<all_urls>"]
}
],
"permissions": [
"tabs",
"activeTab",
"scripting"
]
}
Here is the contents of background.js:
var toggle = false;
chrome.browserAction.onClicked.addListener(function(tab) {
toggle = !toggle;
if(toggle) {
var start_working = function() {
chrome.tabs.query({ url: ["http://*/*","https://*/*"], currentWindow: true }, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
chrome.tabs.executeScript(tabs[i].id, {code : "var enabled = 1;"});
chrome.tabs.executeScript(tabs[i].id, {file: 'js/new.js'});
chrome.browserAction.setIcon({path: "add48.png", tabId:tabs[i].id});
}
});
}
if (!chrome.tabs.onUpdated.hasListener(start_working)) {
chrome.tabs.onUpdated.addListener(start_working);
chrome.tabs.query({url: ["http://*/*","https://*/*"]}, function (tabs) {
console.log('1start_working='+chrome.tabs.onUpdated.hasListener(start_working));
console.log('1toggle='+toggle);
for (var i = 0; i < tabs.length; i++) {
chrome.tabs.executeScript(tabs[i].id, {code : "var enabled = 1;"});
chrome.tabs.executeScript(tabs[i].id, {file: 'js/new.js'});
chrome.browserAction.setIcon({path: "add48.png", tabId:tabs[i].id});
}
}
);
}
} else {
chrome.tabs.onUpdated.removeListener(start_working);
console.log('2start_working='+chrome.tabs.onUpdated.hasListener(start_working));
console.log('2toggle='+toggle);
chrome.tabs.query({url: ["http://*/*","https://*/*"], currentWindow: true }, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
chrome.tabs.executeScript(tabs[i].id, {code : "var enabled = 0; $('#sort_g').remove();"});
chrome.browserAction.setIcon({path: "add48_off.png", tabId:tabs[i].id});
}
}
);
return false;
}
});
Here is the code of manifest.json:
{
"manifest_version": 2,
"name": "Ds",
"version": "0.2",
"background": {
"scripts": ["background.js"]
},
"icons": {
"48": "add48.png",
"128": "add128.png"
},
"browser_action": {
"default_icon": "add48_off.png"
},
"permissions": [
"tabs",
"notifications",
"*://*/*"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/jquery-2.2.4.min.js"],
"run_at": "document_end",
"all_frames": true
}
],
"web_accessible_resources": ["tpl/panel.html"]
}
When we click on the application icon, we add an element to all the HTML tabs and make the icon "active", and when we click the icon again, we change the icon to gray and remove the html element from all pages.
Also, when updating the html tab, the element should again appear and the extension icon should be active.
All this is implemented, but after disabling the extension, an html element still appears, although the new.js script should not be connected and chrome.tabs.onUpdated.hasListener(start_working)=false
Here's the log after disabling the extension:
background.js:49 2start_working=false
background.js:50 2toggle=false
But when updating the tab anyway, the html element appears on the page
I can not understand why this happens? Moreover, the console shows that after disabling the extension, when updating the page, the new.js script is connected already 3 times.
I am working on some experiments that requires to auto generate IDs for elements, I have decided to go with chrome extension.
However, the content script only got triggered when I land on the homepage of the site (e.g. https://secure.checkout.visa.com/). Once I navigate to other pages (e.g. tap on "Create Account"), the script didn't get triggered, I tried to set a break point on the content script but it only got hit on the home page, but not on create account page.
Any idea what went wrong here? Below is the code:
// manifest.json
{
"manifest_version": 2,
"name": "Chrome Auto Gen ID",
"description": "Generate IDs",
"version": "1.0",
"permissions": ["activeTab"],
"background": {
"scripts": ["event_page.js"],
"persistent": false
},
"browser_action": {
"default_title": "Auto generate ID"
},
"content_scripts": [
{
"matches": ["https://secure.checkout.visa.com/*"],
"js": ["jquery-3.2.1.min.js", "auto_gen_id.js"],
"all_frames": true,
"run_at": "document_idle"
}
]
}
The content script:
// auto_gen_id.js
var divs = document.getElementsByTagName("div");
var inputs = document.getElementsByTagName("input");
var sections = document.getElementsByTagName("section");
var count = 0;
function genId(list) {
for (var i = 0; i < list.length; ++i) {
var element = list[i];
if (element.hasAttribute("id")) {
continue;
}
element.id = "gen-id-" + count++;
}
}
genId(divs);
genId(inputs);
The background script:
// event_page.js
chrome.browserAction.onClicked.addListener(function(tab) {
console.log('Generating IDs on ' + tab.url);
chrome.tabs.executeScript(null, {file: "auto_gen_id.js"});
});
Thanks #makyen and #wOxxOm, followed the suggestions below to solve the problem:
Is there a JavaScript/jQuery DOM change listener
Right now, I have an app that always runs the content.js script and replaces all images in the browser that it can find with a different image. I want to make it so that this only happens when you actually click the icon for the extension.
Here is my manifest.json:
{
"manifest_version": 2,
"name": "Unicorn",
"description": "changes images and words to unicorn related ones",
"version": "1.0",
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"content.js"
],
"run_at": "document_end"
}
],
"browser_action": {
"default_title": "Unicorn"
}
}
Here is content.js:
chrome.browserAction.onClicked.addListener(function (tab) { //should be fired when User Clicks ICON
var elements = document.getElementsByTagName('*');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if(isImage(element)){
element.src="http://67.media.tumblr.com/30b1b0d0a42bca3759610242a1ff0348/tumblr_nnjxy1GQAA1tpo3v2o1_540.jpg";
}
for (var j = 0; j < element.childNodes.length; j++) {
var node = element.childNodes[j];
if (node.nodeType === 3) {
var text = node.nodeValue;
var replacedText = text.replace(/wild/gi, 'rainbow bright');
if (replacedText !== text) {
element.replaceChild(document.createTextNode(replacedText), node);
}
}
}
}
});
function isImage(i) {
return i instanceof HTMLImageElement;
}
This works fine without the line chrome.browserAction.onClicked.addListener(function (tab) { and the closing brackets for it. What am I missing here?
The browser action click handler should be moved to Background context for it to work, then you can send a message to current tab.
manifest.json
{
"manifest_version": 2,
"name": "Unicorn",
"description": "changes images and words to unicorn related ones",
"version": "1.0",
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"content.js"
],
"run_at": "document_end"
}
],
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"default_title": "Unicorn"
}
}
background.js
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.sendMessage(tab.id, {
method: 'showImages'
});
});
content.js
function showImages() {
var elements = document.getElementsByTagName('*');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (isImage(element)) {
element.src = "http://67.media.tumblr.com/30b1b0d0a42bca3759610242a1ff0348/tumblr_nnjxy1GQAA1tpo3v2o1_540.jpg";
}
for (var j = 0; j < element.childNodes.length; j++) {
var node = element.childNodes[j];
if (node.nodeType === 3) {
var text = node.nodeValue;
var replacedText = text.replace(/wild/gi, 'rainbow bright');
if (replacedText !== text) {
element.replaceChild(document.createTextNode(replacedText), node);
}
}
}
}
}
function isImage(i) {
return i instanceof HTMLImageElement;
}
// Message handler
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.method === 'showImages') {
showImages();
}
});