Chrome extension is nor running on gmail pages - javascript

I'm trying to create a chrome extension (for personal use) that will run every time I open a gmail message, however I can't seem to get the function to run in gmail pages. When I try it on other pages it runs successfully, but not on gmail. I have tried different kind of listeners and added a couple of alerts as an indication for what's running, but on gmail nothing runs at all.
Manifest:
{
"name": "***",
"version": "0.99",
"manifest_version": 2,
"content_scripts" : [
{
"matches": ["<all_urls>"],
"js": ["agent.js"],
"css": ["style.css"],
"all_frames": true
}
],
"icons": {
"16": "icon16.png",
"48": "icon16.png",
"128": "icon16.png"
},
"browser_action": {
"default_popup": "popup.html"
}
}
agent.js:
function replaceText() {
if ((document.body.innerHTML.search("****")) >= 0) {
alert("Found")
var prev = document.getElementsByTagName("table")...
prev = prev.replace(...)
prev = prev.replace(...)
document.getElementsByTagName("table")... = prev
}
}
window.addEventListener('load', function () {
alert("Started")
replaceText()
})
new MutationObserver(() => {
alert("Started")
replaceText()
}).observe(document, {subtree: true, childList: true});
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
alert("Started")
replaceText()
}
})

Related

Javascript: Browser Extension navigate.clipboard.write() not working in content.js

In my extension I have a button in a popup.js file that runs a listener for a button press and sends a command to a content.js file.
document.querySelector('#btn').addEventListener('click', () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) =>
chrome.tabs.sendMessage(tabs[0].id, { command: 'getClientName' })
);
});
My content.js file is a little involved and grabs some information off the page to copy to the clipbaord, but for purposes of my problem I just need a listener to wait for the command "getClientName" then save a value to the clipboard like below.
chrome.runtime.onMessage.addListener((msg, sender, response) => {
navigator.clipboard.writeText("I did it 2!")
.then(() => {alert("I did it 2!");
})
.catch(() => {
alert("I didn't it 2");
})
});
However, I cannot get navigator.clipboard.writeText() to work from the content.js page. It will only work if I run it directly from popup.js, which doesn't really work since I need to pull information off the page.
Right now it gets sent to .catch() and sends me the error message.
Manifest (replaced the actual URL in my manifest with "all" for privacy reasons):
{
"manifest_version": 3,
"name": "The Magic Button",
"version": "1.0.0",
"description": "Open P.P. client folder in sharepoint",
"action": {
"default_icon": {
"16": "/images/logo16.png",
"48": "/images/logo48.png",
"64": "/images/logo64.png",
"128": "/images/logo64.png"
},
"default_popup": "popup.html",
"default_title": "Open Sharepoint Folder"
},
"permissions": ["tabs",
"clipboardWrite"],
"content_scripts": [
{
"matches": [all],
"js": ["content.js"],
"css": ["/styles/contentStyle.css"],
"run_at": "document_idle",
"all_frames": false
}
]
}
This sample copies the web page title to the clipboard.
manifest.json
{
"name": "hoge",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"scripting"
],
"host_permissions": [
"<all_urls>"
],
"action": {
"default_popup": "popup.html"
}
}
popup.html
<html>
<body>
<button id="copy">Copy</button>
<script src="popup.js"></script>
</body>
</html>
popup.js
const getTitle = () => {
console.log("getTitle() = " + document.title);
return document.title;
}
document.getElementById("copy").onclick = () => {
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);
navigator.clipboard.writeText(result[0].result);
});
});
}

using background.js service_worker on about:blank page with matchAboutBlank:true not working, any workaround?

How can I run background.js (service_worker) in about:blank pages?
I want to do some JS inside Google Slide Presenter tab that opens as "about:blank" (when launching presenter from fullscreen browser).
I set "match_about_blank" : true for content_scripts and inside background.js I also tried using matchAboutBlank: true which didn't help.
I read that activeTab doesn't work with about:blank pages in another post, is there any other way I can achieve this?
manifest.json
{
"name": "Google Slide Presenter",
"description": "Highlight speaker notes with background colour",
"version": "0.1.0",
"manifest_version": 3,
"icons": {
"16": "/images/icon-16x16.png",
"32": "/images/icon-32x32.png",
"48": "/images/icon-48x48.png",
"128": "/images/icon-128x128.png"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/icon-16x16_black.png",
"32": "/images/icon-32x32_black.png",
"48": "/images/icon-48x48_black.png",
"128": "/images/icon-128x128_black.png"
}
},
"content_scripts":[{
"matches": ["https://docs.google.com/*"],
"match_about_blank" : true,
"css": ["somecss.css"]
}],
"background": {
"service_worker": "background.js"
},
"permissions": [
"storage",
"activeTab",
"scripting",
"tabs"
],
"host_permissions": [
"https://docs.google.com/*"
]
}
background.js
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && /^http/.test(tab.url)) {
chrome.scripting.executeScript({
target: { tabId: tabId },
files: ["./foreground.js"],
matchAboutBlank: true,
})
.then(() => {
console.log("INJECTED THE FOREGROUND SCRIPT.");
})
.catch(err => console.log(err));
}
});
foreground.js
document.querySelector(".punch-viewer-speakernotes-text-body-scrollable").style.backgroundColor='yellow';
UPDATE - Able to run the JS but still with errors:
using content_scripts to load the js
"content_scripts":[{
"matches": ["https://docs.google.com/*"],
"match_about_blank" : true,
"css": ["progressbar.css"],
"js": ["foreground.js"],
"all_frames":true,
"match_origin_as_fallback":true,
"run_at": "document_start"
Using in foreground.js
setTimeout(function() {
const container = document.getElementsByClassName('punch-viewer-speakernotes-text-body-zoomable')[0];
if (container.textContent.includes('Speaker')) {
document.querySelector(".punch-viewer-speakernotes-text-body-scrollable").style.backgroundColor='yellow';
console.log('Speaker is contained in element');
} else {
console.log('Speaker is NOT contained in element');
document.querySelector(".punch-viewer-speakernotes-text-body-scrollable").style.backgroundColor='blue';
}
}, 5000);
CONSOLE:
Speaker is contained in element
Uncaught TypeError: Cannot read properties of undefined (reading 'textContent') at foreground.js:5:19
Uncaught TypeError: Cannot read properties of undefined (reading 'textContent') at foreground.js:5:19

Communication of background with content script

Im trying to communicate background with content script, but my way doesnt work. And I want to know why it doesnt work and how to solve this problem(other solutions dont work. idk why).
Manifest.json:
{
"manifest_version": 2,
"name": "X",
"version": "2.0",
"browser_action": {
"default_title": "title"
},
"permissions": [
"activeTab",
"tabs"
],
"content_scripts": [
{
"matches": ["https://*/*"],
"js": ["content_scripts/jquery.min.js", "content_scripts/script.js"],
"run_at": "document_idle"
}
],
"background": {
"scripts": ["background/background.js"]
},
"icons": {
"16": "icon.png",
"32": "icon.png",
"48": "icon.png",
"64": "icon.png",
"128": "icon.png"
}
}
Background.js:
chrome.tabs.query({active: true}, function (tabs) {
tabs.forEach((cur, i)=>{
chrome.tabs.sendMessage(tabs[i].id, {"delBody": true})
})
})
ContentScript:
chrome.runtime.onMessage.addListener(function(obj, sender) {
if(obj.delBody)
document.body.remove()
})
Thanks you very much wOxxOm. Problem was in
The background script runs when your extension is loaded on browser startup/update, when your content script haven't yet been injected
So I solve it like this:
content:
chrome.runtime.sendMessage({"getInfo": true})
chrome.runtime.onMessage.addListener(function(obj, sender) {
if(obj.delBody)
document.body.remove()
})
background:
chrome.runtime.onMessage.addListener(function(obj, sender) {
if(request.getInfo) {
chrome.tabs.query({active: true}, function (tabs) {
tabs.forEach((cur, i)=>{
chrome.tabs.sendMessage(tabs[i].id, {"delBody": true})
})
})
}
})

How can Chrome extension functionality be run independently for each tab?

I've been developing chrome extension for dealing with different tab DOM but with development so far, it seems that an extension can only handle one tab at a time.
background.js has method which calls recursively with 10 sec interval :
function sendMessageScheduler()
{
console.log(tabId); // tab is created for each new tab
timer = setTimeout(function(){
chrome.tabs.sendMessage(tabId, {text: 'click_question',
currentTabId: tabId}, doStuffWithDom);
sendMessageScheduler();
}, 10000);
}
pop.js :
startButtonButton.addEventListener('click', function() {
chrome.extension.getBackgroundPage().sendMessageScheduler();
}, false);
contentscript.js :
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.text === 'click_question') {
}
});
manifest.json :
{
"manifest_version": 2,
"name": "Click Question",
"version": "1.0",
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["*://*.stackoverflow.com/*"],
"js": ["contentscript.js"]
}],
"browser_action": {
"default_icon": "question.png",
"default_title": "Click Questions Plugin",
"default_popup": "popup.html"
},
"permissions": ["activeTab"]
}
What I've assumed before implementing above logic is that the extension will handle each tab independently but with development, it seems that if I execute setTimeout function for one tab, then other tab running setTimeout function stops and vice-versa.
How can I should handle this case so that different timeout function works independently?
You can get all tabs with the following code
chrome.tabs.query({}, function(tabs) {
for (var i = 0; i < tabs.length; i++) {
var tabId = tabs[i].id;
// do what you want
}
});

Chrome Extension detect button inside extension

I am building a simple chrome extension and I need it to change the background color of the selected tab page on clicking a button thats within the extension popup.
<button id="btn">Change</button>
I have tried this:
var b = chrome.extension.getElementById('btn');
b.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
code: '
document.body.style.backgroundColor = "#000"
'
});
});
In the JS file, but it does nothing, what is the problem here?
This is my manifest file:
{
"manifest_version": 2,
"version": "1.0",
"name": "extension",
"description": "extension disc",
"browser_action": {
"default_title": "extension",
"default_popup": "popup.html"
},
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["jquery.min.js"]
}],
"permissions": [
"tabs"
]
}
A popup builds up its own DOM, so you can use var element = document.getElementById('btn') together with element.addEventListener() and chrome.tabs.query({active: true, currentWindow: true}) to get the active tab of the current window
Be sure to provide tab permission in your manifest
Then try this in your popup.js
var b = document.getElementById('btn');
b.addEventListener('click', function() {
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor = "black";'
});
}, false);

Categories