Eli Grey

Title image files in Opera

I recently discovered a method to title image files in Opera. I was experimenting with CSS generated content in regards to the <title> element in various browsers, and discovered that as long as the <head> and <title> elements are not display: none, generated content applied before and after the <title> element is added to the page title itself in Opera. It was obvious to me that I should combine this with HTTP Link: headers containing stylesheets, as to make it possible to modify the title of usually non-titleable media, such as images, plain text, audio, and video.

In this demo, the following CSS rules are applied in Opera.

head, title {
	display: block;
	width: 0;
	height: 0;
	visibility: hidden;
}
 
title::before {
	content: "Just an image — ";
}
Tagged: , ,

Better font smoothing in Google Chrome on Windows

Screenshots: before and after.

Firefox 4 and Internet Explorer 9 already support improved font smoothing offered by the DirectWrite API in Windows 7 and Vista. Google Chrome (WebKit) has yet to support DirectWrite, which may be the deal breaker for you when choosing to use either Google Chrome or Firefox if you are primarily a Windows user.

I recently discovered while messing with the CSS3 text-shadow property in Google Chrome that it somehow improves font smoothing in Google Chrome (but surprisingly not the WebKit-based Safari too). To use the better font smoothing on your website, just use text-shadow: rgba(0, 0, 0, .01) 0 0 1px in your CSS on whatever you want to have better font smoothing. I have also created a Google Chrome extension called “Enhanced Windows Font Smoothing“, which applies this CSS hack to every website and to all text. Please note that smaller text may look a little unsightly, though it will still be completely readable. For a good example website try the extension on, see how the text logo on the Ubuntu Font Family website looks before and after installation of the Google Chrome extension. Please note that this CSS hack may cause adverse side-effects on Mac OS X, so I suggest that you try to target Windows UAs only.

Tagged: ,

Pausing JavaScript with async.js

async.js is a library that aims to make it so you don’t have to mess with callbacks when making applications in JavaScript 1.7 or higher by using the yield statement to pause function execution.

Examples

Please note that user interaction with the page is not blocked during the course of any of these examples.

node.next(eventType) method

The node.next(eventType) method would pause a function until the specified event is fired on the node that next was called on and would return the captured event object.

var listenForNextEventDispatch = function ([node, eventType], callback) {
    var listener = function (event) {
        node.removeEventListener(eventType, listener, false);
        callback(event);
    };
    node.addEventListener(eventType, listener, false);
};
Node.prototype.next = function (eventType) {
    return [listenForNextEventDispatch, [this, eventType]];
};

You could now do the following in an async()ed function to handle the next click event on the document.

var clickEvent = yield document.next("click");
// handle click event here

Asking the user for their impressions of async.js

The following code does not use any obtrusive and annoying functions like prompt or alert yet still can utilize execution-blocking features.

yield to.request("feedback", "POST", (
    yield to.prompt("What are your impressions of async.js?")
));
yield to.inform("Thanks for your feedback!");
// do more stuff here

As opposed to the following, which is functionally equivalent to the previous code but doesn’t use async.js’s blocking features.

async.prompt(
    ["What are your impressions of async.js?"],
    function (response) {
        async.request(
            ["feedback", "POST", response],
            function () {
                async.inform(
                    ["Thanks for your feedback!"],
                    function () {
                        // do more stuff here
                    }
                );
            }
        );
    }
);

That’s a lot of callbacks, all of which are implied when you use async.js.

Creating an async.js module for thatFunctionThatUsesCallbacks

async.yourMethodName = function ([aParameterThatFunctionUses], callback) {
    thatFunctionThatUsesCallbacks(aParameterThatFunctionUses, callback);
};

You could then use yield to.yourMethodName(aParameterThatFunctionUses) and immediately start writing code that depends onthatFunctionThatUsesCallbacks function after the statement.

Extending Object.prototype.toString

Object.prototype.toString is a great way to find the “class” of an object, but it only works for the native constructors like String, Function, ect. Due to this limitation, I have created an open source JavaScript library named toStringX which adds support for non-native constructors so things like the string representation of new Foo are [object Foo] instead of [object Object]. I have also made some examples that you can run to see the toStringX library in action that you can find in the toStringX repository README.

XDomainRequest is no longer IE-only

XDomainRequest is Internet Explorer 8’s cross-domain request function. It would be easy to add support for it in Firefox 3.5 using native cross-domain XMLHttpRequests, but that wouldn’t work in Firefox 3, Opera 9.6-10, and Safari 4. I have created a library named XXDomainRequest (means “Cross-browser XDomainRequest”) that builds on the pmxdr client library to create a fully API compatible version of XDomainRequest. Go to the XXDomainRequest project page to see (and run) the examples that request resources on code.eligrey.com.

Custom error constructors

Most of the time, the standard six native error constructors and the one generic error constructor are not specific enough for an error. What if you want your library to throw a custom SecurityError if it detects an XSS vector on a website? I made a function to create such constructors that behave the exact same way the native error constructors, like SyntaxError by using methods like Error.prototype.toString and the standard error object format. This code makes throwing a custom fake error constructor made with ErrorConstructor("SyntaxError") have the same output as a native SyntaxError in a JavaScript shell. I’ve tested the code in Firefox 3/3.5 and Opera 9.6 and it seems to work fine. Comment and say if it works in your browser too.

function ErrorConstructor(constructorName) {
  var errorConstructor = function(message, fileName, lineNumber) {
  // don't directly name this function, .name is used by Error.prototype.toString
    if (this == window) return new arguments.callee(message, fileName, lineNumber);
    this.name = errorConstructor.name;
    this.message = message||"";
    this.fileName = fileName||location.href;
    if (!isNaN(+lineNumber)) this.lineNumber = +lineNumber;
    else this.lineNumber = 1;
  }
  errorConstructor.name = constructorName||Error.prototype.name;
  errorConstructor.prototype.toString = Error.prototype.toString;
 
  return errorConstructor;
}

Usage: ErrorConstructor([constructorName])
Note: If no constructorName is specified, the default of Error.prototype.name is used
Usage for generated error constructor: errorConstructor([message[, location[, lineNumber]])

Examples:

var SecurityError = ErrorConstructor("Security Error"),
MarkupError = ErrorConstructor("(X)HTML Markup Error");
//these will both throw a SecurityError starting with "Security Error on line 83:"
var xss_error = "Possible XSS Vectorn
 JSON XHR response parsed with eval()n
 Recommended fix: Parse JSON with JSON.parse";
throw new SecurityError(xss_error, "/js/searchResultsJSONloader.js", 83);
throw SecurityError(xss_error, "/js/searchResultsJSONloader.js", 83);
//these will both throw the following MarkupError:
//"(X)HTML Markup Error on line 1: Invalid DOCTYPE"
throw new MarkupError("Invalid DOCTYPE");
throw MarkupError("Invalid DOCTYPE");

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.

More rotⁿ fonts

I previously made two rot13 DejaVu fonts (rot13 DejaVu Sans and rot13 DejaVu Serif) so I thought I might as well make fonts for the other less-widely used rotn ciphers. All of these fonts are based on the open source DejaVu fonts. These are by no way official DejaVu fonts and are just remixes by me under the same license as the normal DejaVu fonts. If you want to distribute the fonts on your website, feel free to do so, and you could optionally link back to me if you want. I don’t care what you do with them. As with all the rotn ciphers, using them twice (ie. using the rot47 font to view rot47 encoded text) will result in the unciphered text. It’s a cipher that decodes what it encodes by doing the same rotations. The example pages require a modern browser that supports webfonts, such as Firefox 3.1 beta or Safari 3.1.2.