how to communicate between a options page and background page of chrome extension - google-chrome

I face a problem. Through message passing I transferred DOM data from content script to background page. What i would like to know is how you can establish a communication channel between Options page and background page. The API chrome.extension.getBackgroundPage() is not useful. Nor is traditional message passing through sendRequest and addlistener working . How do i transfer this data from background page to the options page? Could someone provide a tested snippet to explain?
this is what i have been trying .
In my contentscript.js
<script>
var selected_Text ="";
window.addEventListener("dblclick",function(event){
selected_Text = String(window.getSelection());
chrome.extension.sendRequest({greeting: "maprender",name:selected_Text}, function(response) {
alert("reached here")
console.log(response.farewell);
});
//i am to then load options.html on DOM like this
var Div = document.createElement("iframe");
Div.setAttribute('src', chrome.extension.getURL('options.html'));
Div.setAttribute("style","width:130px;height:80px;position:absolute;left:10px;");
Div.setAttribute("id","xyz");
document.body.appendChild(Div);
</script>
I retreive the selected_Text at background.html like this
<script>
var Addr_details={
place:null
};
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
if (request.greeting == "maprender")
{
alert("reached here sendin resp"+request.name);
Addr_details.place = request.name;
sendResponse({farewell: "goodbye"});
}
else
sendResponse({}); // snub them.
});
</script>
Now to access the value of this text at the options page options.html i tried 2 methods
One was to use chrome.extension.getBackgroundPage() like this:
<script>
function init(){
var bkg = chrome.extension.getBackgroundPage();
alert("the selected text is "+bkg.Addr_details.place);
}
</script>
init is onload of options.html .This does not give me the value . infact it just terminates at initialization of chrome.extension.backgroundPage.
Another approach i tried was to create a similar request(like the one already present at contentscript.js) from contentscript.js with a different greeting and add a listener to it at options.html .That doesnt seem to work either at the receiver side(options page) because i get the callback at the contentscript after the request.I am surely doing something wrong , amnt I ?Please help.

It makes sense for the second approach not work. Options.html is not "alive" all of the time, only when the options page is up. Hence, it cannot listen to requests from the content script.
That's exactly what "background" is for.
As for the first approach (using getBackgroundPage()), I never used this method myself, but it seems to bring back only the DOM of the background page, and therefore you cannot access the variables in the background js.
Your best shot should be to send a request from the options page to the background page, asking for this value, e.g.:
Content script:
chrome.extension.sendRequest({greeting: "retrieveAddr"}, function(response) {
// do something with response.addr...
});
Background page:
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
switch (request.greeting) {
case "maprender"):
alert("reached here sendin resp"+request.name);
Addr_details.place = request.name;
sendResponse({farewell: "goodbye"});
break;
case "retrieveAddr":
sendResponse({addr: Addr_details});
default:
sendResponse({}); // snub them.
});
});
Another, easier but hackier solution is to use localStorage to pass info between the options and background pages, as they both share the same one.

Related

Chrome Extension: Insert a clickable image using a content script

I know hat it is possible, but I am not quite sure how to do it the 'right' way, as to ensure there are no conflicts.
I came across this question: Cannot call functions to content scripts by clicking on image . But it is so convoluted with random comments that it's hard to understand what the corrected way was.
Use case:
Html pages have a div on the page where they expect anyone using the Chrome extension to inject a picture. When users click on he picture, I want to somehow notify an event script. So I know I need to register a listener so the code inserted messages the event script.
Can I get some indication on what code to inject through the content script? I saw that sometimes injecting jquery directly is advised.
I am trying to avoid having the html page to post a message to itself so it can be intercepted. Thanks
With the help of Jquery something like this would capture the image onclick event and allow you to pass a message to a background page in the Chrome Extension:
$("img").click(function(){
var imageSrc = $(this).attr("src");
//Post to a background page in the Chrome Extension
chrome.extension.sendMessage({ cmd: "postImage", data: { imgSrc: imageSrc } }, function (response) {
return response;
});
});
Then in your background.js create a listener for the message:
chrome.extension.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.cmd == "postImage") {
var imageSrc = request.data.imgSrc;
}
});

How to show html files with modal.open using jquery?

Currently i use a fine working code for opening a modal with Jquery :
$(document).ready(function(){
$("span.ico-detail").click(function(){
modal.open({content: "View detail of " + $(this).parent().parent().attr("id")});
e.preventDefault();
});
});
And now the problem is : How can I use modal.open to open a HTML file named "view.html", which contaning the string of "View detail of "?
What should I change the content : "xxx" with, so I can open the HTML file (view.html) and join it with other text ?
Thanks before.
If the view.html is stored on a server and its content is static, then you can choose to preload the content of the file using ajax.
$(function () {
window.myAppNs = {
viewContent: null;
};
$.ajax({
url: 'view.html',
dataType: 'html',
type: 'GET'
}).done(function (resp) {
myAppNs.viewContent = resp;
});
$("span.ico-detail").click(function(){
modal.open({content: myAppNs.viewContent + $(this).parent().parent().attr("id")});
e.preventDefault();
});
});
I am creating a global variable myAppNs. This will hold all app related variables. The idea is not pollute the global namespace with unnecessary variables. There are better and safer ways to create a namespace. If that interests you, you can google for the same.
The ajax call preloads the content of the view.html and stores it in myAppNs.viewContent. The click handler reads that content from the variable.
There is a slight chance that the user can click the element before the ajax response is returned. If that's an issue, you can always move the namespace creation and ajax call out of document.ready and place it in the head section, immediately after referencing jquery. That ought to give the browser enough time to fetch the content before the dom is ready, but there is still that small possibility that the response might be delayed. If you need to ensure the user can click only if the data has been fetched, then bind the click handler inside the done callback of the ajax call.

Chrome extension: how to constantly check URLs on new tabs and then respond with an action for certain URLs?

Hi—I'm not a student or a programmer by trade, but I'm trying to knock up a quick prototype to get an idea across. I've cobbled together some code from other StackOverflow questions, and I've almost got what I need, but I'm having trouble with one thing: the extension will run exactly once, but no more, until I refresh the extension via chrome://extensions. I'm guessing there's something wrong with the element of this program that listens for a new URL, but I can't figure out how to keep that element listening constantly. This code runs in background.js right now, though I've also tried it in background.html.
Basically, I'd like the extension to check the URL of a tab any time the user visits a new page (either by typing the URL herself or clicking through to one), and, if the URL appears in the plugin's internal URL list, to pop up a short notification. I have this so far:
// Called when the url of a tab changes.
// So we can notify users
var notification = webkitNotifications.createNotification(
'48.png',
'Alert!'
);
// Called when the url of a tab changes.
function checkForValidUrl(tab) {
// Compare with a the URL
if (tab.url.match(/google/)) {
//then
notification.show();
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tab);
}
});
chrome.tabs.onSelectionChanged.addListener(function(tabId, selectInfo){
chrome.tabs.getSelected(null, function(tab){
checkForValidUrl(tab);
});
});
I fixed this after hacking it around a little bit -- I don't really have the vocabulary to explain what I did but I thought I'd post the code in case someone else has the same (simple) problem later.
function checkForValidUrl(tabId, changeInfo, tab) {
var notification = webkitNotifications.createNotification(
'48.png',
'Alert!',
'Watch out for your privacy!'
);
// Compare with the URL
if (tab.url.match(/google/)) {
//then
notification.show();
}
};
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tabId, changeInfo, tab);
}
});

How to make chrome remember the one tab(or a window) information that can be used in other tabs

In a chrome Extension , How to make chrome remember the tab information that can be used by other tabs.
For example or being more specific.,
I've a button in one of the tabs that when clicked opens another tab and i used chrome.createtabs for this in Background.html. I also created a variable which will save the tab id of the new tab created (say tab1). I want to use tab1 in myscript.js(content script) to place the information in parent tab. So how can i send the request from background.html to content script?
Or Is there any way to post the content to the webpage using background.html?
btw I used localStorage['tab1'] to save the new Tab ID.
Lemme know if i'm not clear. Thanks
It's all described in Message Passing with examples. To send a message from a background page to a content script:
background.html
===============
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
content_script.js
=================
chrome.extension.onRequest.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"});
else
sendResponse({}); // snub them.
});

about sending messages among bg.html, popup.html and contentscript.js

In my extension, when a button named mybuttonl in popup.html is
clicked, it sends a message "getvar" to contentscript.js, which in turn sends a message "I want var1" to background.html to get an object named var1. (A button named mybutton2 is set up likewise, except it gets the var2 object when clicked).
How should I implement this?
What's more, I am a little confused about the chrome.extension.onRequest.addListener and chrome.extension.sendRequest methods. Could someone please explain?
onRequest.addListener and sendRequest is part of Chrome's extension Messaging. Which is located here http://developer.chrome.com/extensions/messaging.html
Basically, you listen for a request using "onRequest.addListener" that someone sent from triggering a "sendRequest".
In your case, you put a "onRequest.addListener" in your content script to listen for requests coming from the Popup (using sendRequest). And from your content script, you can return a response back to your popup to handle what is happening. In your popup, you have direct access to the background page using chrome.extension.getBackgroundPage().
If you want your content script to communicate to your background page as well (which is not needed since your making stuff more complicated), you can add a "onRequest.addListener" to your background page which only listens for requests coming from the content script. To do that, Message Passing explains it perfectly. "sender.tab" if true, is a content script.
The example below (untested) shows what I mean about message passing. Remember, try to keep stuff simple, not complex.
Example
Popup.html
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: "fromPopup", tabid: tab.id}, function(response) {
console.log(response.data);
});
});
ContentScript.js
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == "fromPopup") {
// Send JSON data back to Popup.
sendResponse({data: "from Content Script to Popup"});
// Send JSON data to background page.
chrome.extension.sendRequest({method: "fromContentScript"}, function(response) {
console.log(response.data);
});
} else {
sendResponse({}); // snub them.
}
});
BackgroundPage.html
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
// From content script.
if (sender.tab) {
if (request.method == "fromContentScript")
sendResponse({data: "Response from Background Page"});
else
sendResponse({}); // snub them.
}
});