Thursday, June 12th, 2008
Category: HTML
, JavaScript
Form validation may seem a little boring, but it is still one of the low hanging fruits for Ajax.
Validanguage is a simple new validation framework that you can access and configure through HTML (via comments rather than attributes) and a JSON API.
For example, if you place the following next to an input, it will flash red if you try to type in anything other than a number, a dollar, or a period (good for a price).
HTML:
-
-
<!-- <validanguage target="example" mode="allow" expression="numeric$." /> -->
-
Or you can configure it via JSON:
JAVASCRIPT:
-
-
validanguage.el.example = {
-
characters: {
-
mode: 'allow',
-
expression: 'numeric$.',
-
onsubmit: true,
-
errorMsg: 'You may only enter numbers, periods,
-
or the dollar sign.'
-
},
-
required: true,
-
errorMsg: 'Please enter a valid monetary amount',
-
onsuccess: 'someObject.successHandler',
-
onerror: [errorHandler1, errorHandler2]
-
}
-
Features
- 100% unobtrusive javascript, name-spaced under the global validanguage object. No inline event handlers required (not even to block form submissions)
- No external libraries required (optional Prototype integration)
- Use inheritance to manage your validation settings. Define a setting globally, per-form, or per-element.
- Supports a choice of two APIs:
- HTML-like API placed inside comment tags. The choice for ease of use and simplicity.
- JSON-based API. For advanced configuration.
Easily configure custom validation functions to be triggered onblur, onsubmit, onchange, etc.
Add onsuccess and onerror callback functions to integrate Validanguage into your existing site design.
All validation functions and onsuccess/onerror callbacks are scoped so that the this keyword refers to the validated element.
A normalized "text" argument is supplied to validation functions for textareas and textboxes.
The inherited error message is automatically supplied to the onerror callback(s) as the first argument.
Easy-to-use keypress suppression.
Wednesday, June 4th, 2008
Category: Firefox
, HTML
, SVG
It seems so obvious once you think about it, but Rob O'Callahan from Mozilla took us by surprise in his blog post demonstrating his experimental branch of Gecko that allows you to apply SVG effects to HTML.

The code for applying the effects above follows:
XML:
-
-
<html xmlns="http://www.w3.org/1999/xhtml"
-
xmlns:svg="http://www.w3.org/2000/svg">
-
<body style="background:#ccc; font-size:30px;">
-
<style>
-
p { width:300px; border:1px solid black; display:inline-block; margin:1em; }
-
iframe { width:300px; height:300px; border:none; }
-
b { outline:1px dotted blue; }
-
</style>
-
<p class="target" style="background:lime;">
-
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
-
ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
-
<iframe class="target" src="http://mozilla.org"/>
-
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
-
<b class="target">elit, sed do eiusmod tempor incididunt
-
ut labore et dolore magna aliqua.</b> Ut enim ad minim veniam.</p>
-
-
<style>.target { clip-path: url(#c1); }</style>
-
<svg :svg height="0">
-
</svg><svg :mask id="m1" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
-
</svg><svg :linearGradient id="g" gradientUnits="objectBoundingBox" x2="0" y2="1">
-
<svg :stop stop-color="white" offset="0"/>
-
<svg :stop stop-color="white" stop-opacity="0" offset="1"/>
-
</svg>
-
<svg :circle cx="0.25" cy="0.25" r="0.25" id="circle" fill="white"/>
-
<svg :rect x="0.5" y="0.2" width="0.5" height="0.8" fill="url(#g)"/>
-
</body>
-
</html>
Rob makes a bunch of good points, such as:
CSS isn't really up to the task [of applying advanced visual effects to HTML]. One problem is that CSS isn't good at manipulating structured values like shapes and filter processing stacks; they're cumbersome to write in CSS expression syntax, or else they require new custom CSS syntax (e.g. @-rules), and there's no standard DOM to let scripts manipulate components of these structured values. Another issue is that we should try to avoid duplicating specification and implementation of complex features.
Contrast that with SVG, which long ago dealt with spec'ing out fancy-pants effects in mark-up and interfacing with JavaScript APIs. In fact, Rob ends his piece with a little snubby-snubby to Flash and Silverlight based both on SVG's status as a standard and its nice integration with page markup:
A nice side effect of providing better SVG-HTML integration is that it gives SVG a leg up on the Web. You can't do these effects using Flash or Silverlight, and since they're not standards they probably won't ever be invited to this party.
Unlike WebKit's shiny new CSS stuff, you can't just yet get a build of this stuff in Gecko:
I'm making tryserver builds right now, and I'll update this post with a link when they're ready. Here's a link to my Mercurial repository.
But it looks like builds are forthcoming. Hats off to Rob for putting together such a cool proof-of-concept.
Wednesday, May 28th, 2008
Category: HTML
, Standards
Mike Chambers has create a nice proof of concept that implements the HTML 5 tag using JavaScript and Flash:
asically, this parses out VIDEO element / tag and its attributes, and replaces it with the appropriate OBJECT or EMBED element to display a Flash video player that loads the specified video. It has support for playing back both h264 content and FLVs.
It uses the SWFObject JavaScript library to display the Flash content.
Currently the following VIDEO attributes are implemented:
- controls
- poster
- autoplay
- width
- height
- playcount
The tricky part will be cleanly implementing the VIDEO DOM scripting API, although I believe that that should also be possible.
To get it working, you just need to include the shim along with the video tag:
HTML:
-
-
<script type="text/javascript" src="swfobject/src/swfobject.js"></script>
-
<script type="text/javascript" src="html5_video.js"></script>
-
-
<video src="http://onair.adobe.com.edgesuite.net/onair/raulph_hauwert_papervision3d.flv"
-
controls
-
poster="testpattern.png"
-
autoplay="true"
-
width="640"
-
height="360"
-
playcount="500">
-
</video>
-
To see an example, go here, and then take a peak at the shim code itself.
Tuesday, May 27th, 2008
Category: HTML
, Standards
Anne van Kesteren gave an XTech presentation on HTML 5 and boiled it down to this:
The Web's language is HTML
The Web's application language is HTML too
HTML is pretty broken
HTML5 to the rescue
Defines processing for all of HTML
Is for Web applications and documents
Is defined in as an abstract language
Can be written in both HTML (HTML5) and XML (XHTML5)
Is a multi-vendor effort
Worked on by overlapping groups: WHATWG and W3C HTML WG
HTML5 is (partially) implemented today
HTML5 can be used today
Great Community! (Wikis, tools, tests, reviewing)
<section>, <footer>, <progress>, <time>, …
<input type=date>, <input pattern=[a-Z]>, …
Immediate mode graphics: <canvas>
<video> and <audio>
SQL storage, offline application cache, drag & drop, editing, …
Get involved: w3.org/html and whatwg.org.
EOP_ERR exception raised: slide 21
Also, Anne pointed out that ruby support has been added to HTML5.
If you are a Ruby hacker, don't get excited. This is a different ruby :)
"Ruby" are short runs of text alongside the base text, typically used in East Asian documents to indicate pronunciation or to provide a short annotation. This specification defines markup for ruby, in the form of an XHTML module.
Monday, May 26th, 2008
Category: HTML
, Library
Omar AL Zabir has posted about a new library called UFrame:
UFrame combines the goodness of UpdatePanel and iframe in a cross browser and cross platform solution. It allows a div to behave like an IFRAME loading content from any page either static or dynamic. It can load pages having both inline and external Javascript and CSS, just like an iframe. But unlike iframe, it loads the content within the main document and you can put any number of UFrame on your page without slowing down the browser. It supports ASP.NET postback nicely and you can have DataGrid or any other complex ASP.NET control within a UFrame. UFrame works perfectly with ASP.NET MVC making it an replacement for UpdatePanel. Best of all, UFrame is implemented 100% in Javascript making it a cross platform solution. As a result, you can use UFrame on ASP.NET, PHP, JSP or any other platform.
To use it you simply setup a div:
HTML:
-
-
<div class="UFrame" id="UFrame1" src="SomePage.aspx?ID=UFrame1">
-
<p>This should get replaced with content from Somepage.aspx
</p>
-
</div>
-
This reminds me a little of purple includes which let you grab pieces of remote documents.
iframes are notoriously slow, and this is one reason why the Caja project exists. If we can trust code to be in the page itself, it can render a lot faster (think widgets in a page).
Also, sometimes I wish I could just say: <div nobleedingcss> around comments in a blog say, so no CSS or formatting from within can effect the outer page (e.g. bad closing of a tag).

Monday, May 5th, 2008
Category: HTML
, JavaScript
John must have had some downtime on Sunday afternoon, as he implemented an HTML parser in JavaScript. The library, that you can play with via this demo, lets you attack HTML in a few ways:
A SAX-style API
Handles tag, text, and comments with callbacks. For example, let's say you wanted to implement a simple HTML to XML serialization scheme - you could do so using the following:
JAVASCRIPT:
-
-
var results = "";
-
-
HTMLParser("<p id=test>hello <i>world", {
-
start: function( tag, attrs, unary ) {
-
results += "<" + tag;
-
-
for ( var i = 0; i <attrs.length; i++ )
-
results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
-
-
results += (unary ? "/" : "") + ">";
-
},
-
end: function( tag ) {
-
results += "";
-
},
-
chars: function( text ) {
-
results += text;
-
},
-
comment: function( text ) {
-
results += "<!--" + text + "-->";
-
}
-
});
-
-
results == '<p id="test">hello <i>world</i></p>"
-
XML Serializer
Now, there's no need to worry about implementing the above, since it's included directly in the library, as well. Just feed in HTML and it spits back an XML string.
JAVASCRIPT:
-
-
var results = HTMLtoXML("<p>Data: <input disabled/>")
-
results == "</p><p>Data: <input disabled="disabled"/></p>"
-
DOM Builder
If you're using the HTML parser to inject into an existing DOM document (or within an existing DOM element) then htmlparser.js provides a simple method for handling that:
JAVASCRIPT:
-
-
// The following is appended into the document body
-
HTMLtoDOM("<p>Hello <b>World", document)
-
-
// The follow is appended into the specified element
-
HTMLtoDOM("<p>Hello <b>World", document.getElementById("test"))
-
DOM Document Creator
This is a more-advanced version of the DOM builder - it includes logic for handling the overall structure of a web page, returning a new DOM document.
A couple points are enforced by this method:
- There will always be a html, head, body, and title element.
- There will only be one html, head, body, and title element (if the user specifies more, then will be moved to the appropriate locations and merged).
- link and base elements are forced into the head.
You would use the method like so:
JAVASCRIPT:
-
-
var dom = HTMLtoDOM("<p>Data: <input disabled/>");
-
dom.getElementsByTagName("body").length == 1
-
dom.getElementsByTagName("p").length == 1
-
One place that you could use this API would be on the server-side. For example, using Aptana Jaxer. Although, you could also interface directly to Java, or just use the Mozilla utilities directly.
Wednesday, April 23rd, 2008
Category: Dojo
, HTML
, Standards
, Unobtrusive JS
Simon Willison pointed out the part of the HTML 5 spec that discusses a way to add attributes to HTML elements for your own needs via data-.
For example, a spaceship for a game:
HTML:
-
-
<div class="spaceship" data-id="92432"
-
data-weapons="laser 2" data-shields="50%"
-
data-x="30" data-y="10" data-z="90">
-
-
onclick="spaceships[this.parentNode.dataset.id].fire()">
-
Fire
-
</button>
-
</div>
-
Every HTML element may have any number of attributes starting with the string "data-" specified, with any value.
These are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
The dataset DOM attribute provides convenient accessors for all the data-* attributes on an element. On getting, the dataset DOM attribute must return a DOMStringMap object, associated with the following three algorithms, which expose these attributes on their element:
Simon points out that "this will be incredibly useful for unobtrusive JavaScript where there’s no sensible place to store configuration data as HTML content. It will also mean Dojo has an approved method for adding custom attributes to declaratively instantiate Dojo widgets."
Monday, February 11th, 2008
Category: Browsers
, HTML
, JavaScript
John Resig has written a Cross-Window Messaging sample using Firefox 3, which implements the current postMessage API in HTML 5. Opera 9 implements a slightly older version, and a new release will fix that of course:
This particular API adds a new method to every window (including the current window, popups, iframes, and frames) that allows you to send textual messages from your current window to any other - regardless of any cross-domain policies that might exist.
Specifically, you're given a new window.postMessage("string") method that generates a message DOM event on the document of the receiving document. This event object contains the message as a property: event.data which the receiving document can use however they see fit.
His example has a sender:
HTML:
-
-
<iframe src="http://dev.jquery.com/~john/message/" id="iframe"></iframe>
-
-
<input type="text" id="msg" value="Message to send"/>
-
-
</form>
-
-
window.onload = function(){
-
var win = document.getElementById("iframe").contentWindow;
-
document.getElementById("form").onsubmit = function(e){
-
win.postMessage( document.getElementById("msg").value );
-
e.preventDefault();
-
};
-
};
-
</script>
-
and a receiver:
HTML:
-
-
-
<b>This iframe is located on dev.jquery.com
</b>
-
<div id="test">Send me a message!
</div>
-
-
document.addEventListener("message", function(e){
-
document.getElementById("test").textContent =
-
e.domain + " said: " + e.data;
-
}, false);
-
</script>
-
He also touches on the security issues:
- If you're expecting a message from a specific domain, set of domains, or even a specific url, please remember to verify the .domain or .uri properties as they come in, otherwise another page will be bound to spoof this event for malicious purposes.
- Just because a string is coming in, as a message, doesn't mean that it's completely safe. Note that in the example, above, I inject the string using .textContent, this is intentional. If I were to inject it using .innerHTML, and the message contained a script tag, it would execute immediately upon injection. This is a critical point: You'll need to be sure to purify all your incoming messages before they are used and injected into the DOM (or sent to the server). This is the same that you would do on the server-side of your application, be sure to take the same precautions here, as well.
Having a standard, blessed, way to talk using this message based system is going to be great for Web developers.