chrome extension dynamically change icon (without clicking) - google-chrome-extension

how can I make my chrome extension change icon (without clicking on it). I've got script that's checking if page has certain string and if it has I want my extension icon change from grey to colored one.

Updated Answer: For Manifest V3
Use chrome.action.setIcon({ path: "/example/path/image.png" }).
Source
Original Answer: For Manifest V2 and Under
The content script will need to send a message when it wants to set the icon e.g.
chrome.runtime.sendMessage({
action: 'updateIcon',
value: false
});
Then in the background script:
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.action === "updateIcon") {
if (msg.value) {
chrome.browserAction.setIcon({path: "/assets/tick.png"});
} else {
chrome.browserAction.setIcon({path: "/assets/cross.png"});
}
}
});

In background you can do stuff like :
const updateIcon = tabId => {
const icon = isDisabled() ? icons.disabled : icons.enabled;
chrome.pageAction.setIcon({ tabId, path: icon });
};
chrome.tabs.onUpdated.addListener(updateIcon);
ref : https://github.com/gbleu/opteamissed/blob/master/background.js#L38

Related

AddEventListener to SharePoint Modal window, so that parent window can execute a function, declared inside the Modal

The following code, included in $(document).ready of the modal window, does not work. Apparently the iframe of the SharePoint modal window has not yet been loaded into DOM, when the addEventListener fires out.
What would be the correct approach to handle this?
window.addEventListener("message", function(event) {
if(event.data == "openpi");{
alert(1)
}
});
Thank you!
There is dialogReturnValueCallback option in SP.UI.ModalDialog.showModalDialog, you could get the value from dialog and then used in parent window.
<script type="text/javascript">
//******** Dialog with Data from Pop Up Starts Here ***********/
function openDialogAndReceiveData(tUrl, tTitle) {
var options = {
url: tUrl,
title: tTitle,
dialogReturnValueCallback: onPopUpCloseCallBackWithData
};
SP.UI.ModalDialog.showModalDialog(options);
}
function onPopUpCloseCallBackWithData(result, returnValue) {
if(result== SP.UI.DialogResult.OK)
{
SP.UI.Status.removeAllStatus(true);
var sId = SP.UI.Status.addStatus("Data successfully populated to text boxes from Pop-up");
SP.UI.Status.setStatusPriColor(sId, 'green');
document.getElementById('<%= txtData1.ClientID %>').value = returnValue[0];
document.getElementById('<%= txtData2.ClientID %>').value = returnValue[1];
}else if(result== SP.UI.DialogResult.cancel)
{
SP.UI.Status.removeAllStatus(true);
var sId = SP.UI.Status.addStatus("You have cancelled the Operation !!!");
SP.UI.Status.setStatusPriColor(sId, 'yellow');
}
}
//******** Dialog with Data from Pop Up Ends Here ***********/
</script>
Check here for details

Opening Tab Next to Active Tab

For my Chrome extension, I need to open a new tab next to the active/current tab. But tab.create method always append the tab at the end of tab list.
Firefox has relatedToCurrent property to set tab position.
Is there any Chrome equivalent for opening tabs next to active tab?
You can use the "index" property to specify the position at calling chrome.tabs.create() function. If you want to open a new tab next to the current tab:
chrome.tabs.query({
active: true, currentWindow: true
}, tabs => {
let index = tabs[0].index;
chrome.tabs.create({
...,
index: index + 1,
...
}, tab => {
...
});
}
);
If you are trying to create new tab from injected content script in a tab next to it then below is the code for content script and background/servicer worker script.
//content script code
chrome.runtime.sendMessage({ open_new_tab: true, url: 'https://www.google.com' })
//background.js or service_worker.js
chrome.runtime.onMessage.addListener( (request, sender, sendResponse) => {
if (request.open_new_tab) {
//sender is the tab the above content script code is injected in
chrome.tabs.create({url: request.url, index: sender.tab.index + 1})
}
//if you are using Manifest V3 then always call sendResponse as below
sendResponse(true)
})

google extension inline install and Verified not working

google.com/webstore i have add my extension
i Have check "This item uses inline install."
Websites: chose Verify site
google.com/webmasters i have add site and Verifyed.
when i put this code on me site:
<link rel="chrome-webstore-item"href="https://chrome.google.com/webstore/detail/itemID">
<button onclick="chrome.webstore.install()" id="install-button">Add to Chrome</button>
<script>
if (document.getElementById('extension-is-installed')) {
document.getElementById('install-button').style.display = 'none';
}
</script>
i click on button "Add to Chrome" install app extension, but when i refresh site button "Add to Chrome" is display. why? i cant Understanding
You're obviously following the guide at https://developer.chrome.com/webstore/inline_installation
In that case, you missed a step.. Let's look at the code.
if (document.getElementById('extension-is-installed')) {
document.getElementById('install-button').style.display = 'none';
}
The condition here is whether an element with ID extension-is-installed is present on the page. But what adds it?
A step back:
For example, you could have a content script that targets the installation page:
var isInstalledNode = document.createElement('div');
isInstalledNode.id = 'extension-is-installed';
document.body.appendChild(isInstalledNode);
So, you need to add a Content Script that adds that element to the page.
However, I doubt that guide will work. By default, content scripts execute after DOM is loaded (and therefore, that hiding script has executed). You can make them run at document_start, but then body does not exist yet.
Let me make an alternative hiding script, based on communicating with the extension using "externally_connectable". Suppose your website is example.com, and your extension's ID is itemID
Add example.com to sites you want to be messaged from:
"externally_connectable" : {
"matches" : [
"*://*.example.com/*"
]
},
In your background page, prepare for the message from the webpage:
chrome.runtime.onMessageExternal.addListener(
function(message, sender, sendResponse) {
if(message.areYouThere) sendResponse(true);
}
);
In your page at example.com, add a button (hidden by default) and code to show it when appropriate:
<button onclick="chrome.webstore.install()"
id="install-button" style="display:none;">
Add to Chrome
</button>
<script>
if (chrome) {
// The browser is Chrome, so we may need to show the button
if(chrome.runtime && chrome.runtime.sendMessage) {
// Some extension is ready to receive messages from us
// Test it:
chrome.runtime.sendMessage(
"itemID",
{areYouThere: true},
function(response) {
if(response) {
// Extension is already installed, keep hidden
} else {
// No positive answer - it wasn't our extension
document.getElementById('install-button').style.display = 'block';
}
}
);
} else {
// Extension is not installed, show button
document.getElementById('install-button').style.display = 'block';
}
}
</script>
Was requested to add page reload after install. chrome.webstore.install has a callback parameter specifically for this.
Instead of using onclick attribute, assign a function:
document.getElementById('install-button').addEventListener("click", function(e) {
chrome.webstore.install(function() {
// Installation successful
location.reload();
});
});

Chrome page action popup disappears

I need a page action popup icon to appear when a tab has a specific URL in the address bar.
I have this in my background page
chrome.tabs.query({url:"MYURL.COM"} , function(tab)
{
for(i=0;i<tab.length;i++)
{
console.log(tab[i].id);
chrome.pageAction.show(tab[i].id);
}
});
The popup shows whenever I reload the extension but as soon as user refreshes, it goes away and doesn't come back.
The reason is that the background.js page is only loaded once, so you need to add a listener to every time the page tab is updated to check whether the page action should be shown, something like this:
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (tab.url.indexOf("MYURL.COM") > -1) {
chrome.pageAction.show(tabId);
}
});
There is no reason to iterate over each tab as you have done.
As Adam has already said, the tabs.onUpdated event is the way to do it.
Anyway, it [seems like I'm not the only one who experienced that the tabs.onUpdated event doesn't always fire when it should - even when waiting for complete status.
So if you're having the same issue, you might want to try my modified version that has proven reliable for me 100%.
chrome.tabs.onUpdated.addListener(function(tabId, change) {
if (change.status == "complete") {
chrome.tabs.query({active: true}, function(tabs) {
var tab = tabs[0];
// Now do stuff with tab .. Eg:
if (tab.url.indexOf("MYURL.COM") > -1) {
chrome.pageAction.show(tab.id); }
else {
chrome.pageAction.hide(tab.id); }
});
}
});
Use chrome.tabs.onUpdated to listen to new tabs and tab reloads of the domain you are interested in.

chrome extension: Injecting code which references a script that I am also injecting - why it fails?

I am trying to create a jquery popup on any page, triggered on demand, when the user presses on my chrome extension.
I have permissions set to [ "tabs", "http:///", "https:///" ]
I have a background page which tries to do the following:
chrome.browserAction.onClicked.addListener(function(tab) {
//chrome.tabs.executeScript(null, { code: "alert(document.title);" }, null);
chrome.tabs.executeScript(null, {file: "demo.js"}, null);
chrome.tabs.executeScript(null, { code: "document.body.appendChild(document.createElement('script')).src='demo.js'" }, null);
});
If I uncomment the alert, it appears when I click on the extension icon.
But with the comment as it is it doesn't do anything.
Any thoughts why it fails?
UPDATE
I managed to get it working, by referencing a url and not a local resource(demo.js).
Now the code, that works, looks like this:
chrome.tabs.executeScript(tab.id, { code: "document.body.appendChild(document.createElement('script')).src='http://iamnotagoodartist.com/stuff/wikiframe.js'" }, null);
My local "demo.js" was a copy of the content from that url anyway.
I am not sure why it doesn't work when I reference the local file... ?
You must use chrome.extension.getURL to get the full path to the "demo.js" file.
chrome.tabs.executeScript(null, {
code: "document.body.appendChild(document.createElement('script')).src='" +
chrome.extension.getURL("demo.js") +"';"
}, null);
BTW if you set tabId parameter to null, the script won't be injected into the background page but into the selected tab of the current window.
You are not passing the tab id to executeScript so the scripts are getting injected into the backround page where you can't interact with them.
chrome.tabs.executeScript(tab, {file: "demo.js"}, null);

Resources