Archive: Web

Page 2 of 6 1 2 3 4 5 6

May 29, 2008

Wii Balance Board hacks

A few days ago, this video appeared with Matthieu Deru and Simon Bergweiler showing off a hack that allows them to surf Google Earth using a Wii. Unfortunately, there weren't too many details about how it was accomplished and I couldn't track down any source for the C# application that talks to the bluetooth device.

What I did find was this other clip from almost a month ago (?!?) in which Daniel Schneider demonstrates using the Wii Balance Board to navigate the web in Firefox.

That's right. You can actually surf the web:

He's using the latest version of GlovePIE (v0.3) to accomplish this. As far as I can tell, it's still very alpha, and the WiiLi wiki claims it's buggy, but it does appear to work. Daniel has some pointers to how he's configured things, including the Greasemonkey script that allows you to surf without clicking.

For more information on coding GlovePIE scripts that use the Balance Board, peek at the documentation.rtf file that's packaged with the GlovePIE download. There's information around page 70 that describes how the board functions and how to pull the 4 sensor values from each of its feet.

Using GlovePIE and Firefox with the Nintendo Wii Balance Board
GlovePIE

Posted by Jason Striegel | May 29, 2008 09:04 PM
Electronics, Firefox, Gaming, Google Earth, Greasemonkey, Web, Windows | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

May 28, 2008

Detect which sites a web user visits

socialdetect_20080528.jpg

Aza Raskin's SocialHistory Javascript library allows you to do something incredibly cool: detect which sites your web users have visited on a per-user basis. The javascript runtime isn't supposed to be privy to the information in a user's browser history, but there's an information backchannel common to all major browsers which allows you to effectively interrogate the browsing history and determine if a particular URL has been visited before.

It works by creating an anchor link to the site in question and applying a CSS style to the link, specifying a different display property for "a:visited". By reading the computed style back from the anchor element, you can then determine the property's value, and consequently if the user had visited the URL or not.

This could probably be used for a number of devious purposes, but Aza's concept for the SocialHistory library is actually really useful. By querying the default URLs that belong to all the major social network sites, you can figure out which sites a particular user visits and custom tailor any social badges that you display. If they use del.icio.us, you show a del.icio.us link. If they visit Digg, you show the Digg button. It's an awesome feature made possible by a pretty freaky security leak.

Now, it's not perfect. It requires that you query the exact URLs that a user may have visited. You can't figure out everywhere they've been, how frequently, or in what order, only whether a particular URL that you know about has been visited before. On the other hand, it's a pretty useful tool considering you aren't even supposed to be able to do this.

How to Detect the Social Sites Your Visitors Use
SocialHistory.js

Posted by Jason Striegel | May 28, 2008 07:44 PM
Ajax, Network Security, Web, Web Site Measurement | Permalink | Comments (1) | TrackBack | Digg It | Tag w/del.icio.us

May 12, 2008

Cross browser session data with Javascript

By storing data in the window.name property, you can store data between page loads and across domains without ever sending a cookie to a server. Thomas Frank created the sessvars.js library which makes use of this browser quirk, allowing you to store up to 2 MB of client-side session data.

This is really powerful for a few reasons:

  • client-side, you can store way more data than allowed by traditional cookies
  • none of the data is transferred explicitly to the server, minimizing bandwidth used for each page request
  • allows you to talk between pages in different domains

Keep in mind that anything you store via this mechanism will be visible to any other site that a person visits, so this is best for storing non-sensitive data that you want to retain between page loads. This would be great for caching returned AJAX data that you would otherwise have to refetch and reprocess.

Session variables without cookies

Posted by Jason Striegel | May 12, 2008 07:26 PM
Ajax, Web | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

May 9, 2008

Processing.js - visualization library for Javascript

jsprocessing_20080509.jpg

John Resig, of jQuery fame, released a port of the Processing visualization language for Javascript. Seriously, John is on fire:

The first portion of the project was writing a parser to dynamically convert code written in the Processing language, to JavaScript. This involves a lot of gnarly regular expressions chewing up the code, spitting it out in a format that the browser understands.

It works "fairly well" (in that it's able to handle anything that the processing.org web site throws at it) but I'm sure its total scope is limited (until a proper parser is involved). I felt bad about tackling this using regular expressions until I found out that the original Processing code base did it in the same manner (they now use a real parser, naturally).

The full 2D API is implemented, with the exclusion of some features here and there between browsers (Firefox 3 is pretty full featured). You can interact with the Processing API directly from standard Javascript. This lets you make use of these drawing features by simply instantiating a Processing object, and then calling its various drawing methods.

Another capability is to write code natively in the Processing language. This allows you to make use of extended language features such as method overloading and classic inheritance, though it looks like type information is pretty much ignored.

John has many of the demos from processing.org working. Most of them are going to peg your CPU, but this is some seriously cool stuff to see working in a first release.

Javascript just got a lot more interesting.

Processing.js
Processing: open source data visualization language

Posted by Jason Striegel | May 9, 2008 09:36 PM
Ajax, Data, Firefox, Software Engineering, Web | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

May 1, 2008

Server-side Google Analytics

Peter van der Graaf did a little analysis of the URLs that are generated by the Google Analytics Javascript API and put together a very useful tutorial for building Analytics-enabled applications without the use of Javascript.

When you look at the analytics javascript code you see that it combines several sets of data into an image request. This image request sends the right data to Google (not the javascript). When you know what url you should use for the image, you can call the image directly and send the same data. Of course you need to be able to request the image url and that isn't easy from another image, rss feed or pdf. This is why we request it "server side".

You can add the code to the PHP that drives a blog site, for instance, and generate page views when your RSS feed is hit. You can even write a very simple script to proxy images and downloads, which will let you track hit data for all files on your site, not just the html pages viewed by a javascript enabled browser.

Taken a step further, you could even use this on the client side, triggering analytics views from standalone Flash apps or even desktop applications.

The one thing you need to keep in mind is that server-side analytics requests will appear to come from your server, not the client's machine. So while you can track page views and download events this way, you'll loose a lot of the information about your user base. Because of this, it would probably make sense to use a separate tracking ID for the server side events.

Google Analytics Without Javascript

Posted by Jason Striegel | May 1, 2008 08:27 PM
Google, PHP, Statistics, Web, Web Site Measurement | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

April 29, 2008

Stop XSS attacks with SafeHTML

If you allow user-contributed content in your site, you run into the problem of dealing with user supplied HTML in a safe manner. The most secure way of dealing with things, of course, is to strip or escape all HTML from user input fields. Unfortunately, there are many situations where it would be nice to allow a large subset of HTML input, but block out anything potentially dangerous.

SafeHTML is a lightweight PHP user input sanitizer that does just that. Just run any input field through the SafeHTML filter and any javascript, object tags, or layout breaking tags will be stripped from the supplied text. It also does a reasonable job of correcting any gnarly, malformed code, which is also a common problem with user-contributed data.

Using it is easy. Just instantiate the SafeHTML object and call its parse method:

require_once('classes/safehtml.php');

$safehtml =& new SafeHTML();

if ( isset( $_POST["inputfield"] ) )
{
  $inputfield=$_POST["inputfield"];
  $cleaninput = $safehtml->parse($inputfield);
}

This will take the posted "inputfield" parameter, strip any baddies, XHTMLify what's left, and the result will be stored in the $cleaninput variable. It's a simple addition to your code, and a lot more straightforward than trying to roll your own.

My only beef with the package is that it's written with a default allow policy, stripping out tags that are in its deleteTags array, but essentially allowing anything else through. If you'd rather only let through tags that you specifically want to allow, I'd recommend adding an allowTags array and adjusting the _openHandler method, adding the following after the deleteTags check:

if ( ! in_array($name, $this->allowTags)) {
  return true;
}

You'll need to fill allowTags with everything you know to be safe and welcome, and you may miss a few that people will end up wanting to legitimately use, but this is easily corrected and the default deny policy is much safer in the long run.

SafeHTML - an anti-XSS HTML parser, written in PHP

Posted by Jason Striegel | Apr 29, 2008 08:49 PM
Network Security, PHP, Web | Permalink | Comments (4) | TrackBack | Digg It | Tag w/del.icio.us

April 22, 2008

Encoding JPEGs client-side in AS3

I've been doing a bunch of Flash Actionscript 3 development lately at work, and one of my favorite features with the new drawing API is the ease and speed with which you can rasterize vector data and manipulate image bitmaps.

What's killer is that Adobe's as3corelib addon library finally gives us some essential tools that have been sorely lacking, none the least of which is a client side JPEG encoder. With this, you can turn any drawable object like a sprite or a movieclip into a ByteArray holding the compressed JPEG data in just a few lines of code. It's as simple as this:

import com.adobe.images.JPGEncoder;

var clipbmp:BitmapData = new BitmapData (aclip.width, aclip.height);
clipbmp.draw(aclip);

var jpgEnc:JPGEncoder = new JPGEncoder(90);
var jpgbytes:ByteArray = jpgEnc.encode(clipbmp);

This turns the "aclip" sprite or movieclip into a rasterized, flattened, BitmapData object. The BitmapData is then run through the JPEG encoder with the quality setting of 90 and you're left with the raw JPEG-compressed image in a ByteArray object. The as3corelib also provides a PNG encoder, with which you can just use the static method PNGEncoder.encode(clipbmp).

This is perfect for saving a capture of user-generated artwork to the server. Just set the data member of a URLRequest object to the ByteArray and post it. For more detailed information on how to put all the pieces together, Henry Jones has a really thorough post of compressing JPEG data and pinging it off a server to force an image download.

Unfortunately, to trigger a JPEG download, you still need to post the image data up to a server script and have it echo it back to the browser. The difference now, though, is that you can do the compression on the client end, saving both server CPU time and the time to upload the image data. This means saving a large image is a few second process instead of taking a minute and a half.

Actionscript 3 Core Library (as3corelib)

Posted by Jason Striegel | Apr 22, 2008 10:03 PM
Flash, Software Engineering, Web | Permalink | Comments (2) | TrackBack | Digg It | Tag w/del.icio.us

April 13, 2008

Nice overview of the YouTube API

I caught this self-referential tutorial on YouTube today which walks you through the basics of the YouTube API. It appears to be quite simple to develop Javascript or Flash applications that can control or interact with the YouTube player, or even completely reskin the interface.

What I didn't know until recently was that the API has provisions for allowing your application to upload videos and post comments. You can even authenticate users and allow them to interact with the YouTube backend through your private application. It looks like you can do just about everything programatically except remove the YouTube watermark on the video.

YouTube Developer's Guide
Developer API Blog

Posted by Jason Striegel | Apr 13, 2008 11:12 PM
Ajax, Flash, Web, YouTube | Permalink | Comments (1) | TrackBack | Digg It | Tag w/del.icio.us

April 11, 2008

Automatic outbound link analytics with jQuery

I had the challenge of adding Google Analytics tracking code to all the outbound links on a site I've been working on. There are hundreds of these links scattered around the site, so rather than try and edit a bunch of links, manually adding onclick handlers in an error-prone fashion, I decided to get lazy and write some code to handle it for me.

First I was thinking about doing some sort of regular expression search and replace throughout the site and database, but that reminded me of CSS3 selectors and their ability to do simple pattern matching. I've seen people apply a special style to outbound links this way, so after a few minutes of monkeying around with things, I now have a chunk of jQuery that will automatically track clicks on all outbound links.

Here it is, in a nutshell:

jQuery(function($){

   // Match all anchor tags in the "maincontent" div with
   // urls that begin with "http" but don't contain the
   // string "yourwebsite.com"
   $('#maincontent a[href^="http"]').not('a[href*="yourwebsite.com"]').click(function(){

     try {

     // Get the href url and toss out the "http://"
     var href = $(this).attr('href');
     if ( href.indexOf("://") > 0 ) {

       // Track the page in Google Analytics as
       // "/tracking/outbound/www.somesite.com/foo"
       var outbound = '/tracking/outbound/' + href.split("://",2)[1];
       pageTracker._trackPageview(outbound);

       }
     } catch( e ) {}
   }
}

With this running, all of my internal pages get tracked as usual, and any external links will appear as pageviews that look like "/tracking/outbound/www.somesite.com/foo".

If you link out to many different pages on several sites, keeping the full site url in the tracking code and building these deep paths is particularly useful. Google Analytics will allow you to drill down into the tree like it was normal content and quickly pull numbers on how many total outbound clicks you received (/tracking/outbound), how many went to www.somesite.com (/tracking/outbound/www.somesite.com), and how many people clicked out to a particular page on the site.

This saved me quite a bit of time and is immensely more flexible than any other outbound tracking method I've used. I hope this helps someone else. Drop me a line in the comments if this works out for you.

Update: it looks like I wasn't the first to do this. An article by Rebecca Murphey shows how to do something similar, while also adding the referring post title to the tracking code. Pretty cool stuff, I must say.

Posted by Jason Striegel | Apr 11, 2008 10:57 PM
Ajax, Google, Statistics, Web, Web Site Measurement | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

April 8, 2008

Relational database using jQuery and HTML tables

Here's a novel use for the HTML <TABLE> tag: storing client side database tables. Nick Kallen came up with a slick hack that uses the jQuery syntax to perform simple selects and joins on HTML tables. By using CSS3 selectors, you can easily target fields which match or contain your search terms, and Nick's jQuery-based API provides a simple query language, similar to a rudimentary SQL:

Today I was thinking aloud about Tree Regular Expressions and how they might make a nice query language for document databases like CouchDB. Someone pointed out that CSS3 selectors might make a great concrete syntax for this. One thing lead to another and I thought, why not build a relational database in HTML? So I did. I even got inner joins working.

Let's start with a few tables:

<table class="users">
  <tr>
    <td class="id">1</td>
    <td class="first_name">amy</td>
    <td class="last_name">bobamy</td>
  </tr> 
  ...
</table>
<table class="photos">
  <tr>
    <td class="id">1</td>
    <td class="user_id">1</td>
    <td class="url">http://www.example.com/foo.png</td>
  </tr> 
</table>

Now we can express some queries:

$('.users')
  .where('.id:eq(1)')
  .select('*')

This is equivalent to SELECT * FROM users WHERE id = 1

$('.users')
  .where('.id:eq(1)')
  .select('.id, .name')

This is equivalent to SELECT id, name FROM users WHERE id = 1

How cool is that? Check out Nick's blog post for an example of text search and an inner join. The API in his jquery.db.js is quite straightforward and only about 50 lines of code. Adding a sort function shouldn't be too difficult.

I'm pretty much convinced now that jQuery is black magic.


Building a relational database using jQuery and <TABLE> tags
Download the jquery.db.js library

Posted by Jason Striegel | Apr 8, 2008 10:02 PM
Ajax, SQL, Software Engineering, Web | Permalink | Comments (1) | TrackBack | Digg It | Tag w/del.icio.us

March 28, 2008

CSS ad blocking for Firefox and Safari

Using Firefox's CSS-based chrome feature or Safari's advanced stylesheet preferences and a little clever CSS coding, you can disable most banner ads, making them invisible in your browser. This technique is considerably easier and more flexible than setting up a private DNS server or proxy to filter out images from ad-serving domains.

The trick is setting up a number of CSS rules that use "*=" substring selection on an element's properties. For instance, matching an IFRAME tag with the SRC parameter containing doubleclick would look like IFRAME[SRC*="doubleclick"] and matching an anchor tag with an HREF containing a url with "ads." in it would look like A:link[HREF*="ads."]. Giving the style "display: none ! important" to all of the possible combinations and adding the stylesheet to your browser's chrome effectively turns off the ad-serving web. The site below has a comprehensive CSS file that's been tailored to assassinate ads from most networks.

To be honest, I didn't realize that you could do this type of parameter matching and subselection in CSS, so it's worth looking at the CSS source for that alone. If you don't use it for this purpose, perhaps the technique will come in handy for something else you are working on.

Better Ad Blocking for Firefox, Mozilla, Camino, and Safari
Ad Blocking userContent.css

Posted by Jason Striegel | Mar 28, 2008 09:20 PM
Firefox, Life, Lifehacker, Mac, Web | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

Design Coding: web standards rap

Next time you're trying to explain the importance of web standards in modern web design and development, just let this video do the talking for you.

The Poetic Prophet (AKA The SEO Rapper) is back with another marketing rap. This time he describes how web standards and proper design can affect the ranking and conversion of pages on your site.

I know this isn't the usual fare here, but I feel I'd be remiss in my duties if I didn't include it in our compendium of all things hack.

Posted by Jason Striegel | Mar 28, 2008 08:00 PM
Music, Web, YouTube | Permalink | Comments (2) | TrackBack | Digg It | Tag w/del.icio.us

March 21, 2008

Easiest cross-browser CSS min-height

Enforcing a minimum height for block elements in HTML is one of those few CSS tricks that you can't live without. There are still enough folks using IE6, unfortunately, and it doesn't support the min-height or min-width CSS parameters. This has caused the invention of a number of different hacks and browser-conditional style sheets to get the desired effect.

Many of the different methods work well, but after trying a number of them, I can say that the following method is the easiest to use and is compatable across all common versions of Firefox, Safari, and IE. Many of you are probably already using this method—it's not new—but for those of you who aren't, give it a try. It should save you a lot of headaches.

Cross Browser min-height

.foo {
min-height:100px;
height: auto !important;
height: 100px;
}

This works because all of the more recent browsers will understand and respect the min-height setting as well as the !important designation. So in the example above, the block will be given the min-height setting you specify, and the height:auto will take precendence over the height:100px, even though it appears earlier in the code. With content shorter than 100px, the min-height setting is observed, and with content that is longer, the block is sized to fit the content.

In the case of older versions of IE, neight the min-height parameter nor the !important designation are supported. Instead, the browser essentially sees a height:auto, immediately followed by a height:100px, and the latter takes precendence. Lucky for us, height parameter in older versions of IE function exactly like the min-height parameter. When content expands past the size of the element, it grows to accommodate it. When content is shorter, the specified height is respected.

I don't find myself using it as much, but this also works with min-width:

Cross Browser min-width

.bar {
min-width:100px;
width: auto !important;
width: 100px;
}

Posted by Jason Striegel | Mar 21, 2008 08:31 PM
Web | Permalink | Comments (9) | TrackBack | Digg It | Tag w/del.icio.us

February 25, 2008

Botanicalls Twitter: flora tweets

botanicalls_20080225.jpg

With Monday finally wrapping up, it's time to start thinking about next weekend. Why not spend it Twitter-enabling your house plants?

Botanicalls Twitter answers the question: What's up with your plant? It offers a connection to your leafy pal via online Twitter status updates that reach you anywhere in the world. When your plant needs water, it will post to let you know, and send its thanks when you show it love.

I've managed to make it through the winter with only two plant casualties so far. There isn't a whole lot I can do about the scarcity of light in Minneapolis, but with a little Arduino hacking I could at least remove watering issues from the equation.

Botanicalls Twitter - Link

Posted by Jason Striegel | Feb 25, 2008 08:42 PM
Electronics, Home, Life, Web | Permalink | Comments (0) | TrackBack | Digg It | Tag w/del.icio.us

February 14, 2008

Nifty Corners: roundtangles made simple

niftycorners_20080214.gif

Since the border-radius CSS parameter has been too slow in coming and rounded corners don't seem to be going out of style any time soon, everyone web developer I know has their own personal brand of CSS background-image and DIV gymnastics for creating smooth-cornered roundtangles. Besides the extra load time that's required to download all those corner images, it's just a lot of extra work. The general principle of unnecessary work is against my slacker sensibilities, which is why the Nifty Corners Cube javascript library caught my attention.

Nifty Corners uses Javascript to dynamically add rounded corners to HTML elements at runtime, without the use of images. You can choose a corner style and tell Nifty Corners what CSS id, class or element to apply it to. The javascript function will dynamically alter the specified elements, drawing 1px high DIV strips at the top and bottom of the element to give it the rounded corners. The effect can be used for everything from rounded content areas to tab-menus.

It won't solve every problem—rounded borders, in particular, are still a bit of a nuisance—but it'll make your work a lot easier for many design challenges and it's compatible with Firefox, Safari and IE 5.5-7.0.

Nifty Corners Cube - Link

Posted by Jason Striegel | Feb 14, 2008 08:57 PM
Web | Permalink | Comments (2) | TrackBack | Digg It | Tag w/del.icio.us

Page 2 of 6 1 2 3 4 5 6

Bloggers

Welcome to the Hacks Blog!

Brian Jepson.Brian Jepson


Jason Striegel.Jason Striegel


Philip Torrone.Phillip Torrone



See all of the books in the Hacks Series!
Advertise here.

Recent Posts

www.flickr.com
photos in Hacks More photos in Hacks