Tag Archives: Programming

Updating the badge in a Windows 8 JavaScript App

Windows 8 apps can have notification badges in the tiles. It’s easy to update the badge, but it’s still not well documented, so here is a small snippet to show you how it’s done:

var Notifications = Windows.UI.Notifications;
var updater = Notifications.BadgeUpdateManager.createBadgeUpdaterForApplication();
var xml = Notifications.BadgeUpdateManager.getTemplateContent(
    Notifications.BadgeTemplateType.badgeNumber
);

xml.getElementsByTagName('badge')[0].setAttribute('value', 5);

var notification = Notifications.BadgeNotification(xml);
updater.update(notification);

Replace the 5 in line 7 with the number of your choice. The end result looks like this:

Badge update example

More info on badge updates is available in the Windows.UI.Notifications namespace of the WinRT and the Badge Update XML Schema.

Gchat now available in the Marketplace!

screen1 screen4 screen5

Gchat, the awesome Google Talk client Luis and I built for Windows Phone, is now available in the Marketplace! We’ve been working on it for a long time and we’d love to know what you think.

Click the button below to go to the Marketplace now and download it!

Download Gchat

We hope you enjoy using Gchat! If you find a bug or want to suggest a new feature, please report it.

StickyTiles: A Windows Phone app to pin sticky notes!

chromescreen1chromescreen2chromescreen3

StickyTiles is a simple Windows Phone Mango app that lets you pin short sticky notes to your start screen! Choose text, color, and back side of the sticky tile. Pin all the sticky tiles you want.

StickyTiles is open source, fork the code at GitHub!

StickyTiles is now available in the Windows Phone Marketplace and is compatible with all Mango phones. Click the button below to download it.

Download StickyTiles

Sierpinski’s Tetrahedron!

pyr

For my Computer Graphics class we had to do Sierpinski’s Triangle in OpenGL. As optional extra credit, we could expand it to 3D. I took up the challenge, and this was the result. It’s not perfect, but it looks really cool!

As always, grab the code at Gist. Comments, forks and improvements are appreciated. :)

New versions of Postponer and ChromeMilk released

screen-gmailI’ve released new versions of my Chrome extensions Postponer and ChromeMilk.

Postponer 0.4 add a one-click add mode to Adder and customizable popup size to Manager, as well as a few bug fixes.

ChromeMilk 0.9.6 features a brand new icon as well as numerous bug fixes.

As always, you can get them from the Chrome extensions gallery:

Postponer Adder

Postponer Manager

ChromeMilk

Thanks to everyone that reported bugs, and a special thanks to Camila González for the new icon in ChromeMilk.

Please let me know of any bugs, issues, feature requests or just general comments you may have. Enjoy the extensions!

Code snippet: Get a weather condition using Python and Google Weather API

Here’s a simple Python code snippet for finding the weather condition of any given city using Google’s Weather API. It’s also published on GitHub if you want to clone it.

import urllib2

def getWeather(city):

    #create google weather api url
    url = "http://www.google.com/ig/api?weather=" + urllib2.quote(city)

    try:
        # open google weather api url
        f = urllib2.urlopen(url)
    except:
        # if there was an error opening the url, return
        return "Error opening url"

    # read contents to a string
    s = f.read()

    # extract weather condition data from xml string
    weather = s.split("<current_conditions><condition data=\"")[-1].split("\"")[0]

    # if there was an error getting the condition, the city is invalid
    if weather == "<?xml version=":
        return "Invalid city"

    #return the weather condition
    return weather

def main():
    while True:
        city = raw_input("Give me a city: ")
        weather = getWeather(city)
        print(weather)

if __name__ == "__main__":
    main()

Update: GitHub is awesome because it allows very easy forking. Beau Martínez has made a fork of my script that includes Python 3 support, XML parsing instead of RegEx searching, and temperature reporting.

How to build a Chrome extension, Part 4: Background pages and scheduling requests

One of the most common uses for an extension is as a notifier. For example, the Google Gmail Checker, an official Google extension and the most popular one in the gallery, constantly checks your Gmail inbox for new unread mail.

This functionality is easy to add into your own extension. You need to add a background page, which is easily added by adding the background_page option to your manifest.json:

{
	"name": "My Extension",
	...
	"background_page": "background.html",
	...
}

Like almost every other component in a Chrome extension, background.html is a standard HTML file. However, it can also do things most web pages cannot, such as cross-origin requests if permissions are correctly added to the manifest. For example, if your extension is a Gmail checker, it would need permissions to http://www.google.com and https://www.google.com. To add these permissions, the manifest.json would be edited to:

{
	"name": "My Extension",
	...
	"background_page": "background.html",
	"permissions": ["http://www.google.com/", "https://www.google.com/"],
	...
}

A background page runs at all times when the extension is enabled. You cannot see it, but it can modify other aspects of the extension, like setting the browser action badge. For example, the following example would set the icon badge to the number of unread items in a hypothetical service:

function getUnreadItems(callback) {
	$.ajax(..., function(data) {
		process(data);
		callback(data);
	});
}

function updateBadge() {
	getUnreadItems(function(data) {
		chrome.browserAction.setBadgeText({text:data.unreadItems});
	});
}

So now you can make a request, but how can you schedule it so the data is retrieved and processed regularly? Luckily, JavaScript has a method called window.setTimeout to do just that:

var pollInterval = 1000 * 60; // 1 minute, in milliseconds

function startRequest() {
	updateBadge();
	window.setTimeout(startRequest, pollInterval);
}

That was easy! Now just slap a

onload='startRequest()'

on the background page’s body tag and that should do it!

But what if you want to stop the request? That can easily be done as well, by chaging the startRequest function a little and adding a stopRequest function:

var pollInterval = 1000 * 60; // 1 minute, in milliseconds
var timerId;

function startRequest() {
	updateBadge();
	timerId = window.setTimeout(startRequest, pollInterval);
}

function stopRequest() {
	window.clearTimeout(timerId);
}

And that’s about it on building background pages that can schedule requests. Now go! Make an awesome notifier! You can even make things like a timer with this (Facebook addiction control, anyone?). Just remember to leave a comment telling everyone of your awesomeness.

How to build a Chrome extension, Part 3: Loading any web page in a popup

Chrome allows extensions that use its page action or browser action API to show popups when clicked. To add this popup, you’d add a popup.html file to your extension and the following to the manifest.json for browser actions:

{
	"name": "My Extension",
	...
	"browser_action": {
		"default_icon": "myicon.png",
		"popup": "popup.html"
	}
	...
}

Or for page actions:

{
	"name": "My Extension",
	...
	"page_action": {
		"default_icon": "myicon.png",
		"popup": "popup.html"
	}
	...
}

However, the popup page is static and cannot be changed while the extension is running. Also, only a local extension page can be put into a popup; you can’t load an external page.

So how can you fix this? Using a relatively old web technique called an iframe. Inline frame, or iframe, is an HTML element that can load any web page inside another in a type of box. So, even though you can’t load an external web page as your popup, you can load it within it.

A simple example for a Bing search extension would be:

<html>
<head>
	<style type="text/css">
	body {width:200; height:300;}
	</style>
</head>
<body>
	<iframe src="http://m.bing.com" width="100%" height="100%" frameborder="0">
	</iframe>
</body>
</html>

As you can see, I have loaded the mobile version of Bing, http://m.bing.com. Because of the small amount of screen real estate available on the popups, loading mobile versions of a page is a good idea as they are minimalistic and require less space.

I’ve also explicitly declared the size of the page (200 by 300) and the iframe (100% of the page). You can change this to what fits your extension best.

(Yeah, I know it is ironic to build a Chrome extension centered on Bing, but I couldn’t get Google’s mobile search to load correctly in an iframe.)

On Chrome, the Bing search extension would look like this:

image

You can download the completed Bing extension from the Chrome Extensions Gallery and the source code (under the GPLv2) from Mediafire.

Now, what if you want to load a different page depending on an extension option? You can easily do this by constructing the iframe element dynamically when the page loads, like this code excerpt from ChromeMilk:

$(document).ready(function() {
	var popup = localStorage.popup || 'igoogle';

	var frame = document.createElement('iframe');

	frame.setAttribute('width', '100%');
	frame.setAttribute('height', '100%');
	frame.setAttribute('frameborder', '0');
	frame.setAttribute('id', 'rtmframe');

	if (popup == 'gmail') {
		// open gmail gadget
		$('body').height(300).width(200);
		frame.setAttribute('src', 'http://www.rememberthemilk.com/services/modules/gmail/');
	}
	else if (popup == 'iphone') {
		// open iphone web app
		$('body').height(480).width(320);
		frame.setAttribute('src', 'http://i.rememberthemilk.com/');
	}
	else if (popup == 'mobile') {
		// open mobile web app
		$('body').height(300).width(200);
		frame.setAttribute('src', 'http://m.rememberthemilk.com/');
	}
	else {
		// igoogle and default
		$('body').height(400).width(400);
		frame.setAttribute('src', 'http://www.rememberthemilk.com/services/modules/googleig/');
	}

	document.body.appendChild(frame);
});

This way, the extension sets the popup size and the iframe location based on a setting saved by the user.

There are a few limitations of this method. Most importantly, you can’t manipulate the iframe once it is loaded, as this is cross-side scripting and is prevented by the browser for security reasons.

That’s about it on loading external web sites in popups. You can use this for a number of things. I’ve mentioned mobile sites, but things like iGoogle widgets also work well.

Do you have any tips on building Chrome extensions based on popups? Or are you having trouble building your extension? Leave a comment!

How to build a Chrome extension, Part 2: Options and localStorage

An important aspect of almost all extensions is being able to save user settings. This can be achieved in Chrome easily by using the localStorage object and Chrome’s extension API options page.

Adding an options page

To add an options page to your extension, make an options.html file in your extension’s folder and add the “options_page” line to your manifest.json like so:

{
  "name": "My Extension",
  ...
  "options_page": "options.html"
  ...
}

localStorage

localStorage is an HTML5 object used for storing web page data locally using JavaScript. Chrome gives extensions the option of using localStorage to save options and data.

Saving options

To save a string to localStorage, use the following code, replacing mysetting and myvalue with your own:

localStorage["mysetting"] = "myvalue";

Or, equivalently:

localStorage.mysetting = "myvalue";

Loading options

To load an option, just access the setting member in the localstorage object:

myvar = localStorage["mysetting"];

Or, equivalently:

myvar = localStorage.mysetting;

It’s always a good idea to make sure you’ve loaded a valid setting. For example, the following code loads a favorite color, but if the current color is not valid, it loads the default value:

var defaultColor = "blue";

function loadFavColor() {
	var favColor = localStorage["favColor"];

	// valid colors are red, blue, green and yellow
	if (favColor == undefined || (favColor != "red" && favColor != "blue" && favColor != "green" && favColor != "yellow")) {
		favColor = defaultColor;
	}

	return favColor;
}

Erasing options

You can erase an option by removing it from the localstorage object, like so:

localStorage.removeItem("mysetting");

Building an options page

Continuing with the favorite color example, lets now build a complete options page for our color-choosing extension. The options.html page would look like this:

<html>
<head>
	<title>Options for Color Chooser</title>
	<script type="text/javascript" src="options.js"></script>
</head>
<body onload="loadOptions()">
	<h1>Favorite Color</h1>
	<select id="color">
		<option value="blue">Blue</option>
		<option value="red">Red</option>
		<option value="green">Green</option>
		<option value="yellow">Yellow</option>
	</select>
	<br />
	<button onclick="saveOptions()">Save</button>
	<br />
	<button onclick="eraseOptions()">Restore default</button>
</body>
</html>

For the behavior of the page, options.js would look like this:

var defaultColor = "blue";

function loadOptions() {
	var favColor = localStorage["favColor"];

	// valid colors are red, blue, green and yellow
	if (favColor == undefined || (favColor != "red" && favColor != "blue" && favColor != "green" && favColor != "yellow")) {
		favColor = defaultColor;
	}

	var select = document.getElementById("color");
	for (var i = 0; i < select.children.length; i++) {
		var child = select.children[i];
			if (child.value == favColor) {
			child.selected = "true";
			break;
		}
	}
}

function saveOptions() {
	var select = document.getElementById("color");
	var color = select.children[select.selectedIndex].value;
	localStorage["favColor"] = color;
}

function eraseOptions() {
	localStorage.removeItem("favColor");
	location.reload();
}

And that’s about it! You can also save and load localStorage data elsewhere in your extension, as the data is shared between all your extension’s files.

Any question, remark, or addition? Please leave a comment!

How to build a Chrome extension, Part 1: Basics

image

Building Chrome extensions is super-easy. I’ve already made two: ChromeMilk and Postponer. I wanted so share my method of building extensions, so I’m going to write a series of posts. This one will cover the basics on how to set up a good development environment and how to begin writing the extensions.

1. Install Chrome dev channel

The Chrome dev channel has the latest technologies and the best developing tools. Install it and use it to debug extensions.

2. Get a text editor to write the code in

If you’re really Spartan you can use regular Notepad. I use Notepad2 because it’s light but has syntax highlighting and other features. There are many available, so take your pick.

3. Learn HTML, CSS and JavaScript

Chrome extensions are made using the same techniques used to make web pages. HTML for content, CSS for presentation and JavaScript for behavior and interaction. I highly recommend the tutorials at W3Schools if you are just starting out. If you’ve been building web pages for a while, you can probably skip this step.

4. Follow the official Getting Started tutorial

Google has a very good tutorial for writing your first extension. This tutorial shows you how to build a simple extension and test in on your browser. After this, you should be ready to build your own extension!

5. Now what?

Now that you know how to build a basic Chrome extension, it’s time to let your imagination run wild! Read the extension documentation and see what you can build with it. Start small and don’t be afraid to be wrong. When your extension is ready, you can submit it to the Chrome Extensions Gallery so that everyone can use it!

I’ll be writing more posts on this, so stay tuned.

Do you have any tips for building Chrome extensions? Have your made an extension after following these steps? What other resources do you use to make extensions? Leave a comment and tell us all about it!