December 2013

Ludum Dare 28 – Make a game in 48 hours

Ludum Dare is an event where people all around the world attempt to make a game in 48 hours, based on a theme voted on and announced at the start of the competition. There are no prizes, it’s more of a challenge to generate ideas and get people to make games.

I’ve wanted to participate in Ludum Dare for a couple years now and it just happened to fall on a completely free weekend for me this time, so I made my first HTML5 game.

Well, I consider it a prototype at this point. I used an HTML5 framework called Phaser, which I’ve had my eye on for awhile but haven’t worked with before. I spent a ton of time learning the framework through the excellent documentation and examples on the Phaser website.

I feel it was a success as now I have a working game prototype, instead of just a vague idea in my head. There is plenty of work to do but I feel it was definitely a worthwhile way to blow a weekend.

Check out my entry on the Ludum Dare website here:

http://www.ludumdare.com/compo/ludum-dare-28/?action=preview&uid=15070

 

P.S. – I’m running off about 10 hours of sleep over the weekend, please excuse the rambling nature of this post.

Refactoring Incremental Reader, or How to highlight text across nodes in the DOM

The last few days, I’ve been able to carve out some time to get back to working on Incremental Reader. My short term goal is to get a more sane structure so I can go back and add unit tests. I was recently exposed to Test Driven Development through a Coursera class “Introduction to Systematic Program Design“, and I’m pretty excited to figure out how to work this into my development process.

Highlighting text! As easy as 1,2…

The last feature I implemented was the right-click context menu to highlight selected text in the current browser tab. Correctly inserting tags to create the highlighted text was a huge pain, mainly because I want notes(highlighted text) to span multiple DOM elements and split anywhere (including the middle of an element). It’s been a bit since I’ve worked on the extension, so I thought I’d walk through the code to refresh my memory on how I implemented this feature.

First to get the selected text:

var highlightRange = window.getSelection().getRangeAt(0);

This returns a Range object, which can contain full nodes and parts of text nodes. The range object has a startContainer and an endContainer property which indicates the node at the start and end of the range. When these are equal, our range doesn’t cross through other nodes, making our job easy. All we have to do is split the node at the start and end offsets, and wrap the new node with with any tag containing a background(highlight) color.

var startContainer = highlightRange.startContainer;
var endContainer = highlightRange.endContainer;
var newNode = document.createElement('mark');
newNode.style.backgroundColor = "yellow";

if (startContainer == endContainer) {
    var splitNode = startContainer.splitText(highlightRange.startOffset);
    var temp = splitNode.splitText(highlightRange.endOffset);
    var insertElement = startContainer.parentNode.insertBefore(newNode, splitNode);
    insertElement.appendChild(splitNode);
} else {

First, we get the nodes where the range starts and ends. The .startOffset property of the range object contains the offset from the start of the node where the highlight began. .splitText() breaks a node at a given offset and returns the portion after the offset as a new node. The .endOffset is actually still remains correct (it’s updated on splitText), so we don’t have to worry about recalculating that value, we simply call it again to split the node at the end of the highlight.

Screenshot Highlighting a single DOM Node

splitNode now contains the node we want to visually highlight on the screen. To do this we create a <mark> element, style it, and insert it in the correct location. This is as easy as just getting the parentNode of our splitNode, and using insertBefore to insert it as a child element, just before the splitNode.

We then use .appendNode to move the node into the new <mark> element. If you use .appendNode on an existing element in the DOM, it will remove it from it’s current position and add it to the new location.

Now we’re done and that was pretty simple, right? Here’s where it gets a little more tricky. Imagine you want to start highlighting a note in the middle of an <h3> and end a few elements away on another <h3> or a <p> element. We can’t just split and wrap the entire block with one tag, it will break the DOM structure.

Screenshot - Highlight across multiple DOM nodes

The solution I came up with is to split the first element and the end element, then wrap all the elements with <mark> individually. Since the <mark> element is just for the user to have visual confirmation of the notes they’ve highlighted on the page, I have no problem with doing it this way. I also haven’t thought of any other solutions, so there’s that too.

After we have split the start and end node, we extract just the text nodes, since these are what we want to wrap. The only way to do this is to extract the the text nodes of range.commonAncestorContainer, meaning the closest element that wraps around the entire range.

Now we’ve all the text nodes including those of the parent container of our highlighted text. To get rid of all the extra nodes, we can use Range.intersectsNode to determine which nodes in our list are actually in the selection. Then, we just loop through our nodes and wrap them all with a <mark> element. You can check out the full code here: content.js on Github

Screenshot Successful DOM highlighting

Refactoring

I’ve got way too much going on in the popup code. I’m going to try to consolidate everything I can into the event script. I’m not sure if the popup page is even going to stay, as the plan is to have a management view to manage articles and notes. The popup might be redundant, as saving pages can be done with a context menu instead.

I’ve also been working out a new way to structure the data. Right now all pages are stored as an array in localStorage. Each item in localStorage is an array containing the url, page title, and the current vertical location of the window (scrollTop or pageYOffset ). This was fine for testing but I plan to store much more info.

Here is the current working list of how I plan to restructure it:

// Collection of articles, future possibility to group articles
articleCollection {
    articles:        // list of articles

    // methods
    save:            // save to local storage
    load:            // retrieve from local storage
}

article {
    url:             // url of article
    prevLocation:    // scrollTop or pageYOffset
    notes:           // list of notes
    created:         // date article added
    accessed:        // date last accessed
    archived:        // bool, allow user to set when done reading

    // methods
    save:            // save article to collection
    remove:          // remove article from collection
}

note {
    content:         // raw text content of note
    location:        // original DOM node position, may help
                     // when locating note on page reload

    // methods
    save:            // save note to article
    remove:          // remove note from article
}

You can see I’ve tried to structure everything in a little bit more of an object oriented way. I’ve added some possibilities for helper methods, but haven’t added getters. I’m not sure that I need to hide any of the data (i.e. wrap in a closure), but I’ll consider that in the future.

You can see I’ve got a pretty good start on getting this up and running, but I’ve still got some more planning to do. I haven’t even gotten in to adding unit tests yet!

Using domain registration to optimize your search engine ranking

There are many ways your domain name can help or hurt your search engine ranking. You can use a few of the following tips when registering your domain, or registering domains for micro-sites or campaigns for your business.

Keywords in domain name

Placing the most important keywords in your domain name can significantly contribute to a page ranking. There are many ways you can incorporate a keyword in a domain name.

Exact match domain

This is great for a campaign or a micro-site. If a customer is searching for ‘recycled shoes’, recycledshoes.com will have an advantage over other domains since the domain name matches the search query exactly. Beware that spammy sites do this all the time, and many exact matches might be hard to obtain. If you find one that works for you, make sure you provide useful content on the site. This is where creating a useful micro-site based around a single product, or subset of products will help. Redirecting the domain to your main business domain is likely to gain you nothing.

Keyword in domain

Just having one of your main business focus keywords in your domain will help your ranking. If your company is named ‘Acme’, and you focus on tools, acmetools.com will be a better domain than just Acme.

Making the keyword the first word in the domain name is also a popular strategy. There is evidence that this technique may be more beneficial than placing a targeted anywhere else. In this example we could try: toolsbyacme.com.

There is also evidence that keywords as sub-domains are factored into rankings. This is great for micro-sites as well. You might run a campaign to push anvils, so you would set up a site at anvils.acme.com targeting anvil sales.

Domain age

Domain age and registration length is also known to be a factor. Both have been mentioned by Google’s resident webspam team member Matt Cutts. 

There isn’t much you can do about domain age except to register early and never let your domain expire. Spend the extra money and register your domain for longer than a year at least. There is controversy around whether the registration length is really a factor, but if you plan to stay around for a few years it makes sense to go ahead and register long term.

Others

Private domain registration has been mentioned as a factor by Matt Cutts before. There are legitimate reasons to have a private domain. If you’re running a solo home based business and you don’t want to broadcast your address and phone number on WHOIS it you may want to stay private. Most small businesses with a phone number and a PO box should list it publicly on their domain WHOIS. This lets Google and everyone else know you’re a legitimate business.

If you operate specifically out of a certain country, or provide a local service, consider using a country specific TLD, like .uk, .ca, .jp, etc… This helps search engines know what country you operate out of, although it’s not the only way they determine your locality. Consider registering multiple TLD’s localized to each area you operate.

Conclusion

Your domain name is just a small factor in your overall search engine ranking, some of these tips will help push you above the competition. This is all provided you have actual useful content on your site. Content is always king, but every little optimization helps.

Setting up a TLD for local web development in Ubuntu

Like any good developer, I have a local LAMP server set up so I can develop locally before pushing a site or app to a live production site. This allows me to completely test any modifications to the code base and helps minimize and prevent any possible bugs once the site is live. Once everything is well tested and good to go, I can easily push to production, test again, and be confident everything is working correctly.

My development server is a 64-bit Debian Server running inside a VirtualBox VM on my desktop PC. I run Ubuntu based Linux distributions on all my PC’s, so I could install a LAMP stack on any of them, but I prefer to keep it separated. By using a virtual machine I can more closely emulate the most common server I deploy to, which also minimizes any bugs I might run in to.

So what does all this have to do with setting up a local development top level domain?

Well, my standard process has always been something like this:

  1. Create a directory for project on local server
  2. Set up new virtual host in Apache (usually ‘project.dev’)
  3. Update /etc/hosts file to point ‘project.dev’ to virtual machine’s ip

That works fine, but I have to add project.dev to any computer on the network that I want to be able to access the .dev site. It’s one of those things that I just have been doing for so long that I do it unconsciously. As a developer, I’m always looking for ways to streamline processes and be more efficient.

Enter dnsmasq

What I want is to make the .dev TLD always point to my virtual machine. Wildcards are not supported in your /etc/hosts file on Linux, so we’ll use dnsmasq.

Dnsmasq is a lightweight, easy to configure DNS forwarder and DHCP server.

You can set up dnsmasq on all the local computers on your network to make them all hit your development VM for all request to *.dev.

If dnsmasq is not already installed on your Ubuntu based distro, a simple ‘sudo apt-get install dnsmasq’ will do.

Next, edit /etc/dnsmasq.conf and add this one line:

address=/.dev/172.24.35.130

Where 172.24.35.130 is the ip of your VM. My VM is exposed with a bridged connection to allow it open access to the internet and the local network.

You may need to restart network-manager & dnsmasq:

sudo service network-manager restart
sudo service dnsmasq restart

And you’re good to go. Now you can clean out that /etc/hosts file you’ve been piling domains on.

This is a simple, easy, and somewhat obvious fix, but sometimes you get into a routine and forget to check if your processes can be optimized.