show page action popup on click - google-chrome

I'm making a chrome extension that uses pageAction.
I can set when it shows whether I want it to have a popup or handle the click myself.
What I want to do is handle the click myself, but with certain scenarios I don't want to process the normal code, and want to show the user a message. Preferably with a popup.
But it seams I can either make the pageAction have a popup or have an onClick. But not both.
I can show an alert, but that is ugly.

Currently, there is no "neat" or official way to handle both. You can just do either. But there are some work arounds that some Google extension product have done.
First of all, set it up to show the popup. And within your pageAction popup, you can have the initialization code to be something like this:
Page Action Popup:
function init() {
if (getClickBehaviour() == 'popup')
handlePopup();
else
openPage();
}
function getClickBehaviour() {
return localStorage['CLICK_BEHAVIOR'] || 'popup';
}
function openPage() {
chrome.tabs.create({url: 'http://google.ca'});
window.close();
});
}
init();
Then you can let your options, set the click behavior. If you want different behaviors on each click, you can do that too.
As you noticed, we are closing the popup right after for the "default" behavior that we don't want the popup to show. That is currently the only way to implement different behaviors.

I haven't tested this myself yet, but have you tried setting the popup to the empty string when you want to handle the click (chrome.pageAction.setPopup('')) and to your popup when you want to show a message. I'm not perfectly sure if the onClicked event handler gets called in that case (where the popup is dynamically set to the empty string), but it's worth looking into.
As far as I know, there is generally no way to programmatically open a popup window for a page or browser action. (Which is too bad, I would love this functionality; but you can imagine some of the annoyances if this were possible.)

Related

Changing chrome extension html using chrome storage event listener

With this code I want to create an event listener for whenever chrome storage updates.
I want 2 things to happen when the event listener is triggered:
The code will console log the updated values. This part works.
I want the HTML for the extension (the document that opens in the corner when you click the icon) to update and render the data value that is in chrome storage. This is that part I need help with.
chrome.storage.onChanged.addListener(function(changes, namespace) {
//part 1
console.log('New data type is %s. New value is %s',
changes['type'].newValue, changes['data'].newValue)
//part 2
document.getElementById('output').innerHTML =
changes['data'].newValue
});
I realize that calling "document" inside the function doesn't make sense, but I'm unsure how to move forward to get it to render in the extension's HTML.
I tried creating an event listener for when the context menu is accessed (users can update the chrome storage but clicking a button in the context menu) but I couldn't get it to work. Also the event should trigger when chrome storage is updated, not when the context menu is simply accessed.
Right now I get this error:
Error in event handler: TypeError: Cannot set property 'innerHTML' of null
(There is an element with id 'output', so that isn't the problem)
Thanks for your help!
The background script runs in a separate hidden background page. It's not related to the browserAction or pageAction popup page, it doesn't have any of the popup page elements, its DOM is empty except for the auto-generated script tags of the background scripts.
The popup is also a separate page and just like any normal page its environment/DOM exists only when the page is shown. You can't modify it when it's not shown. You can't show it from your code in general case either.
Solution 1
Put that onChanged listener in popup.js script that's loaded in your popup.html (declared as "browser_action": {"default_popup":"popup.html"} in your manifest.json) using the standard <script src="popup.js"></script> tag. It will update the popup page if it's shown, and to display the current values when the popup opens read them with chrome.storage.local.get or chrome.storage.sync.get depending on which storage you're using in your extension.
Solution 2
Use chrome.notifications API to show a small notification at the bottom of the screen, see also the official demo extensions.
Solution 3
Use chrome.browserAction.setBadgeText to display short text like a temperature right under the extension icon. Don't forget to declare at least "browser_action": {} in your manifest.json.

How to create a window that is like default popup?

I have a browser action button. When the button is clicked, I need to do some computation and decide which window to open.
If I set default_popup in manifest.json, the popup looks like this.
Since I need to do some computation and decide which window to open, I do in the following way.
chrome.browserAction.onClicked.addListener(function(tab) {
if(...)
url="1.html";
else
url="2.html";
chrome.windows.create({url:url, type: "popup"});
});
But the window created has border and is not at the button's position.
How do I create a window that looks like the default popup?
If you dont figure out how to catch the event before the popup runs, you may do this (I do it for an extension of mine): Assuming both popups have the same width-height, always show popup1, and redirect (navigate to the other one) if it should show popup2. If you want to avoid flashing make sure both popups have fixed and equal body sizes.

Creating a notification from within a notification

I'm creating an extension for Chrome, and one of the functionalities included is the ability for the end user to add people as contacts.
Currently, the contact is saved to the database via AJAX, after which a desktop notification is displayed telling the user that the deed has been done.
However, I would want to first ask the user if he's sure he wants to do that. So I got the mad idea of wanting to create a new notification from within a notification.
So first, the confirmation HTML notification would be created from the background.html, and displayed. It contains a button, and upon clicking it, it should run the AJAX function and create a second notification, containing the feedback.
However, I seem to be unable to do this. I can't run createNotification() from the notification, sendRequest() doesn't seem to go through neither, and I can't use the onClose listener from background.html, because I want to differentiate between clicking the "Yes" button and the "No" button.
Is there any way I can do this? And if not, how should the confirmation dialog be implemented instead?
Have you tried using chrome.extension.getBackgroundPage()? This may provide the access to your background page's API that you require. For example, your first notification page calls the following when Yes is clicked;
function yesClicked() {
chrome.extension.getBackgroundPage().showSecondNotification();
}
The background page declares the showSecondNotification method as follows;
function showSecondNotification() {
webkitNotifications.createHTMLNotification(
chrome.extension.getURL('notification2.html')
).show();
}
Hopefully, this will cause the second notification to be displayed. I've used a similar method in my extensions before but only to retrieve information from the background page. However, I see no reason this shouldn't work.

chrome extension popup and background ajax

I have a requirement where the background.html continous to update every 10 minutes and when I click on the popup it should trigger the background to update immediately and show the result in the popup.
I have the background updating using ajax working and I have the popup trigger the background to make an immediate update using ajax working as well. However, I am stuck on how to display the latest result in the popup...how can I tell when the background ajax call is complete and show the latest result in the popup?
thanks
Well, if you want to listen for changes on the Background Page, you have two ways to do what you want.
In your Popup, you can register chrome.extension.onRequest.addListener in your Popup page, and in your background page you can chrome.extension.sendRequest when you get stuff updated.
You have direct access to the Popup DOM, you can get an instance from chrome.extension.getViews({type:'popup'}), and once you get that, you can just call a method in that DOM. From the popup, you can access the background page easily too with chrome.extension.getBackgroundPage(). For both cases, you get a DOMWindow returned.
I personally would use #2 because you belong in the same extension process, you do not need to communicate to an injected Content Script.
var popups = chrome.extension.getViews({type: "popup"});
if (popups.length != 0) {
var popup = popups[0];
popup.doSomething();
}
Hope this helps.

How do I focus an existing tab in a window? (web page, not extension)

I'm trying to focus an existing tab when the content reloads. The usual window methods don't seem to work.
Here's whats happening: On page_1 I have a link like...
Go to my other page
If the tab doesn't exist, when the link is clicked it opens a new tab and takes focus. (Perfect)
If you then go back to page_1 and click the link again, it reloads the content in the existing tab (perfect) but doesn't focus (crap). I've tried the usual window.focus, $(window).focus methods on load with page_2 without luck.
Any recommendations?
It is impossible.
The following appears to work in IE8 and FF13:
<script type="text/javascript">
// Stupid script to force focus to an existing tab when the link is clicked.
// And yes, we do need to open it twice.
function openHelp(a) {
var tab = window.open(a.href, a.target);
tab.close();
tab = window.open(a.href, a.target);
return false;
}
</script>
Help
There is a workaround to this. Use javascript to open a window in a new tab, store a reference to that tab, and when you want to focus it; close it first and then re-open it.
if (window.existingWindow != null)
try { window.existingWindow.close(); } catch (e) { };
window.existingWindow = window.open("/your/url", "yourTabName");
We use a similar approach to opening the preview pane of the current page you're working on in our service called Handcraft where the above works as expected (we wanted the new window to always focus).
Without using a framework you can put a script block at the bottom of your page that will run once the page loads. Because it is after your HTML you can be assured that the HTML is refers to is actually available.
The script can set the focus to the element you want.