How we can add popup for context menus - google-chrome

I have created a chrome extension. I have used Selection and all context menus. I want to know how we can add popup error if any text is not selected from the page.
If any text selected then it should not show any error message.

Please find below code to display pop up:
chrome.contextMenus.create({
id: "context1",
title: "selected",
contexts: ["all"]
});
chrome.contextMenus.onClicked.addListener(function(info, tab) {
if (tab) {
if (info.menuItemId === "context1"){
var code = 'alert("text selected");';
chrome.tabs.executeScript(tab.id, { code: code });
}
}
});

Related

Can't get the selected text / highlighted text from the tab in my chrome extension

I am developing a chrome extension. I am trying to get the selected/highlighted text from the active tab and do something with it. For now, say all the extension does is writing what the selected text is on a popup. I can't seem to do it. I tried a lot of methods. content script, background scripts. Nothing works. in my manifest.jsonI have permissions for activeTab, contextMenus. I tried multiple functions that take the selected text but nothing works. Example of some functions
const text = (window.getSelection) ?
window.getSelection().toString() :
document.selection.createRange().text;
console.log(text)
chrome.contextMenus.create({
id: 'selectionGetter',
title: 'send selected text',
contexts: ['selection'],
});
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.sendRequest(tab.id, {method: "getSelection"},
function(response){
const url=response.url;
const subject=response.subject;
const body = response.body;
console.log(body)
});
});
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.sendRequest(tab.id, {method: "getSelection"},
function(response){
sendServiceRequest(response.data);
});
});
Would love your help
See How to access the webpage DOM rather than the extension page DOM? for full explanation, here's a quick illustration:
chrome.tabs.executeScript({code: 'getSelection().toString()'}, ([sel] = []) => {
if (!chrome.runtime.lastError) {
document.body.textContent = 'Selection: ' + sel;
}
});
If you have default_popup declared in manifest.json then put this code in popup.js, and put <script src=popup.js></script> in popup.html. It will run each time the popup is shown.
Otherwise put it inside chrome.browserAction.onClicked listener in the background script.

How to check if extension has been activated in each tabs?

I created a Chrome extension. The function works fine in a single page.
Currently the problem is that how to check if the extension has been activated in each tab. So I can re-initialise the toolbar icon.
Steps to reproduce:
1. In page A, active the extension, change toolbar icon to close icon.
2. Open a new page B, the icon still keep using close icon.
I just want to make the toolbar icon reflect to each page.
I try to use tabs onUpdated, but it will affect the extension activated page.
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
chrome.browserAction.setIcon({
path: "images/logo.png"
});
});
You could call chrome.browserAction.setIcon() passing tabId key, like:
chrome.browserAction.setIcon({
tabId: my-tab-id,
path: {"images/logo.png"}
});
You could also update the icon from background to all tabs, when some condition happens, so you could do something like this:
if (someCondition) {
chrome.tabs.query({}, function(tabs) {
tabs.forEach(tab => {
chrome.browserAction.setIcon({
tabId: tab.id,
path: {"images/logo-A.png"}//ICON A
});
});
});
} else {
chrome.tabs.query({}, function(tabs) {
tabs.forEach(tab => {
chrome.browserAction.setIcon({
tabId: tab.id,
path: {"images/logo-B.png"}//ICON B
});
});
});
}

Google Chrome Extension - Get DIV and Other Info Near Clicked Element

My Google Chrome Extension currently retrieves the ImageURL which was right-clicked from the menu, but that's not enough. I also need to do this:
Get the DIV Element inside which this specific Image was clicked.
Get some text strings stored inside this DIV, or in sub-DIVs, next
to the clicked image.
So far I have this, which is working:
background.js
// Add context menu for Images
chrome.contextMenus.create({
"title": "Get this Image",
"contexts": ["image"],
"onclick" : getInfo
});
function getInfo(e)
{
var imgURL = e.srcUrl;
// Set up an event which Content will receive
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {url: imgURL}, function(response) {
alert('Response in Background');
});
});
}
contentscript.js
// Listener for Background Event Sends
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
// print Image Src URL in a custom Content-created place
divHTML = request.url;
document.getElementById('infoDiv').innerHTML = divHTML;
});
Where do I do the extra work to analyze the DOM tree and retrieve extra surrounding elements? In the Background or in the Content?

How to tell if a page is loaded as a popup or in a separate tab in chrome extension

My Chrome extension has a page that is seen in a popup or as a separate tab. When it seen as a separate tab, I need to show a small button at the corner of the page. But I couldn't find a way to detect when a page is loaded in its own tab.
Use chrome.extension.getViews, which returns an array of window objects.
var tabs = chrome.extension.getViews({ type: "tab"})
if(tabs[0]) {
console.log("inside tab")
}
var popups = chrome.extension.getViews({ type: "popup"})
if(popups[0]) {
console.log("inside popup")
}
Or chrome.tabs.getCurrent, which returns a tab object in the callback.
chrome.tabs.getCurrent(function(tab) {
if(tab) {
console.log("inside tab")
} else {
console.log("inside popup")
}
})

pass dom element from background script to chrome.tabs.executeScript

I'm trying to pass the active dom element when the contextmenu is clicked from my background script to a script that is being called through chrome.tabs.executeScript. I can pass booleans and strings just fine, but i always get an error when i pass dom elements. I'm starting to think it's not possible.
//doScripts function called from browser action
chrome.browserAction.onClicked.addListener(function(tab) {
doScripts(true, null);
});
//doScripts function called from context menu click
function getClickHandler(info, tab) {
var currTarg = document.activeElement;
console.log("currTarg = " + currTarg);
doScripts(false, currTarg);
}
//i reference doingBrowserAction and contextTarg in myscript.js
function doScripts(context, targ){
chrome.tabs.executeScript(null, {code: "var doingBrowserAction = "+context+"; var contextTarg = "+targ+";"}, function(){
chrome.tabs.executeScript(null, {file: "js/myscript.js"}, function(){
//all injected
});
});
}
//setup context menu
chrome.contextMenus.create({
"title" : "DESTROY!",
"type" : "normal",
"contexts" : ["page","selection","link","editable","image","video","audio"],
"onclick" : getClickHandler
});
i reference doingBrowserAction and contextTarg in myscript.js. I know what i'm trying to do is possible because the adblock extension does it, but having a hard time figuring out how. thanks in advance.
You cannot get a direct reference to a content script's DOM element from the background page, because the background page runs in the extension's process, and the content script runs in the tab's process. See also https://code.google.com/p/chromium/issues/detail?id=39507.
The document.activeElement property in the background page refers to the active element in the background page's document. As you can imagine, this value is quite useless.
If you query the state of the currently right-clicked element, bind an event in the content script. In the next example, I've chosen the contextmenu event, because context menus can also be opened through the keyboard.
This example adds a context menu option that removes the last active element from the document.
// content script
var lastElementContext;
document.addEventListener('contextmenu', function(event) {
lastElementContext = event.target;
}, true);
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (lastElementContext && lastElementContext.parentNode) {
lastElementContext.parentNode.removeChild(lastElementContext);
lastElementContext = null;
}
});
Background script:
chrome.contextMenus.create({
title: 'DESTROY!',
contexts: ['page', 'link', 'editable', 'image', 'video', 'audio'],
onclick: function(info, tab) {
chrome.tabs.sendMessage(tab.id, 'doDestroy');
}
});