Eli Grey


mumbl is a JavaScript library that makes it easy to play music and create playlists on web pages.


A demo is included with mumbl but if you dont want to download it, there is also an online demo.

Please note that mumbl is not the player in the demo. mumbl is the back-end and the demo is just an example of using mumbl.

Supported Platforms

Supported Platforms

  • HTML5
    • Firefox 3.5+
    • Google Chrome 4+
  • SoundManager 2 (version 2.95b.20100323+)
    • Firefox 1.5+
    • Opera 10+
    • Google Chrome 1+
  • Songbird 1.4+


API documentation can be found in the readme.


  • 0.1.1
    • Better error handling.
    • loaderror event.
  • A while after version 0.1 is released
    • Create a simple library that makes all MP3, OGG, WAV, etc. links be able to be played using mumbl.
    • Make the demo mumbl-powered music player (it will be renamed “mumblr”) portable and reusable.
    • Remove jQuery dependency from mumblr.
    • Make the track title display scroll (maybe using a <marquee>) when it overflows.
  • Version 0.2
    • Full compatability with every major browser.
  • The distant future (maybe version 1.0)
    • Create a simplified flash audio back-end for mumbl that integrates much more nicely and has a smaller file size than SoundManager2.

APNG feature detection

I have made a simple script that utilizes the HTML5 <canvas> API in only 9 functional lines of JavaScript to detect if a browser supports APNG images. It can be useful for deciding when to serve a client browser APNG images instead of GIF images.
This will set the variable, apng_supported to true if the browser supports APNG.
I have also created a demo that uses this script.

(function() {
	"use strict";
	var apngTest = new Image(),
	ctx = document.createElement("canvas").getContext("2d");
	apngTest.onload = function () {
		ctx.drawImage(apngTest, 0, 0);
		self.apng_supported = ctx.getImageData(0, 0, 1, 1).data[3] === 0;
	// frame 1 (skipped on apng-supporting browsers): [0, 0, 0, 255]
	// frame 2: [0, 0, 0, 0]

JavaScript Shell 1.4 Extended

Whenever I open up the JavaScript Shell 1.4 to test some JavaScript out, I don’t like that I have to use the default JavaScript version while testing out code. Generators, let expressions, and various other improvements to JavaScript can be pretty useful but they require an explicit JavaScript version to be declared, so I modified it and added support that will allow JavaScript code up to 2.0 (you can test higher versions by increasing _JS_version_check.end). I call it JavaScript Shell 1.4 Extended. Think of it as the unofficial 1.5 version. If you want the bookmarklet, it’s on this bookmarklet page.

This works by redefining the main shell input eval function multiple times under different JavaScript versions, incrementing by 0.1 for each tag added (they are later removed).

There are also a few other various modifications which you can read about on my JavaScript Shell Extended project page.

Cross-browser accessors

Xccessors is a script I made which implements the legacy methods for defining and looking up object accessors (getters and setters) of objects in JavaScript using ECMAScript 3.1’s accessors standard. This is aimed at adding support for the legacy method in IE8 RC1. Read more on the Xccessors project page. There is also a demo you can try out.

Update: I just tested the script in IE8 RC1 and it seems that IE8 RC1 only supports getters and setters on the DOM and the window object. So as long as you are setting an accessor on the window object or a DOM element, Xccessors should work fine.

jData completely redone

I have recently completely redid all of jData to make a much securer version. I have also dropped the HTTP query parameter support due to most new advanced browsers support postMessage & localStorage (except Opera, which seems to currently only support postMessage).

The old version wasn’t practical due to having no security system that asked the user if they allowed an action, and the messages were just eval()’d right away. The new version features a much more reliable trust sytem that asks the user for confirmation before anything is set by an untrusted host. Getting data has no restrictions, though, like always. Only setting and removing data and requesting to become a trusted host prompt for user confirmation.

The jDataQuery() snippet I made is now obsolete (but still works as long as you make valid JSON requests that comply with the jData API Reference), and is replaced by JIL, an interface library for jData I also made today.

Tagged: , ,

New jData API

Update: Please note that this information is obsolete and does not work with the new completely-rewritten jData host library.

When not using the postMessage API but using the HTTP query parameters API, you used to have to use the “callback” parameter and do something like callback=location.href="http://example.com/%3Fvalue="+encodeURIComponent(jdata)+"%26item="+locacation.search.replace… (and some code to figure out what item is being used) to be able to add support for browsers that support localStorage but not postMessage via server-side. I have simplified this by adding an “r” parameter. The r parameter is a URI that the jData frame will redirect to and you can include two different variables in the URI.

The first parameter is %i, which is automatically replaced with the item being accessed. The second parameter is %v, which is the value of the item being accessed.

Example: http://jdata.eligrey.com/?get=personal.fullname&r=http://example.com/?item=%i&value=%v

This redirects to http://example.com/?item=personal.fullname&value=Elijah%20Grey for me. If an item is not set, %v will either be null (Firefox & Safari nightlies) or undefined (IE) depending on the browser, but as not to confuse with a string of “null” or “undefined”, I have it return an empty string when it is undefined or null.

Tagged: ,

CiteDrag drag and drop script

Firefox 3.1 beta 2 recently added support for the standard drag and drop model (also with some extra Mozilla-only ones). I had an idea to automatically add citation info to text dragged from websites to plain and rich text editors using this newly supported API. I named the finished script CiteDrag, which requires no setup other than adding a single script tag anywhere in your website’s page. CiteDrag is licensed GNU LGPL and free to download in two flavors: CiteDrag and CiteDrag + Drag Image. CiteDrag + Drag Image is all of the normal CiteDrag code with some additional code to give a fancy canvas-generated drag image that shows the text content being dragged. CiteDrag is mostly useful for when someone blogs about another person’s blog post. Having the text automatically go into a cited blockquote and having a link back is very useful. I have installed CiteDrag on this blog and I have a demo of it and a rich text area you can use to test out CiteDrag fully.

Here are some examples of what it does when you drag various data types to various input areas: (Note wherever it says title, it will be replaced with the host name of the source page if there is no page title)

  • Drag a link or image (or linked image) to a normal text input: { [link URI] or [image URI] } via {source title} ( {source URI} )
    • Example:  http://example.com/ via Foobar ( http://foo.bar/post/example.com-ftw/ )
  • Drag a link or image (or linked image) to a rich text input: { [clickable link to link URI] or [image URI] or [clickable image linked to link URI] } via {clickable link to source page with title as text}
  • Drag formatted or non-formatted text to a normal text input: “{Text dragged}” ― {source title} ( {source URI} )
    • Example:  “Lorem ipsum dolor sit amet.” ― Eli Grey ( http://www.eligrey.com/ )
  • Drag formatted or non-formatted text into a rich text input: The dragged text goes into a <blockquote cite=”{source URI}”> and after the blockquote is ― {clickable link to source page with title as text}
    • Example:

      Lorem ipsum dolor sit amet.

Passwords viewer

Less than a year ago, I made a passwords viewer written in XHTML and JavaScript to view exported xml files from the Password Exporter Firefox addon. It was made to make human-readable (I know XML is readable but the exported XML can be much harder to read than tables and if you have it Base64 encoded you would have to decode all of the Base64 encoded attributes, one by one) text tables with the hosts, usernames, and passwords in the exported xml files for my personal use. The text table dynamically resizes with the longest values and is meant to be stored in a text file encrypted with a master password. I was using my passwords viewer today and thought I would share it with everyone else who uses Password Exporter.

You can download the passwords viewer (XHTML) or try out the online version (also XHTML) displaying a text table of a fake example passwords file. Due to this webapp being meant to help out people who use a certain Firefox addon, I only made it so it works in Firefox. Disregard that, I made it cross-browser* with 1 small tweak. The normal version is made for local use on your computer’s filesystem ONLY and the online version works both online and on your computer’s filesystem but requires you tto type out the filename instead of picking it with a file picker. Appending a query or hash string containing file=FILENAME to the end of the URI will auto-load the passwords file specified.

*Except for IE. I see no reason to waste my time on making something like this work in IE.


jData – publicly share data

jData is a new (extremely tiny) library for sharing data about yourself everywhere without a website needing permission/URIs/ect. It is like having a globally accessible localStorage. It is accessible at jdata.eligrey.com in two different API flavors: postMessage and HTTP queries. It only works in browsers that support window.postMessage (ie. advanced browsers like Firefox 3 and the WebKit nightlies) and sorta works in IE 8 beta 2. I may add Google Gears support someday.

What is jData? – Think of the data stored on jData like cookies with no size limit; cookies that can be accessed by any website on the internet. It’s so lightweight that the postMessage API is exactly 300 bytes.
Why make this? – This would be a good resource for storing info about yourself that you are okay with any website on the internet knowing.

Hypothetical situation: Facebook started storing your name (with your permission) to jData.fullname. Then the people who run MySpace think this is a good idea and implement it too. Then other websites start checking jData and see if jData.fullname has been set already and pre-fill the corresponding input text box with your name on a sign up page.