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: HTML
, Dojo
, Unobtrusive JS
, Standards
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: HTML
, JavaScript
, Browsers
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.
Monday, January 28th, 2008
Category: HTML
, JavaScript
, Examples
, Unobtrusive JS
, jQuery
One of my main annoyances with writing code tutorials is that you need to maintain code in several locations: the code itself and the examples in the tutorial document. This is not really a problem when you can use a scripting language or print out the tutorials from a CMS, but when you just want people to get an HTML document you're in trouble. As I am right now writing a lot of articles I didn't want to waste my time and thought about using Ajax to load the code I am documenting into the HTML on the fly. The result looks something like this:

All you need to do is to add jQuery, the script and a class of "codeexample" to a link in the document you want to display. The script creates a PRE element with the code inside, replaces all the special characters, tabs with spaces and adds line numbers. For example:
HTML:
-
-
<p><a href="ordered.html" class="codeexample">ordered.html
</a></p>
-
If you only want to show certain lines (which you'll have to do if you want to explain some code step-by-step) you can define the lines as a list including ranges. Say you want to display line 5, 10 and 12 to 21, then you'd add:
HTML:
-
-
<p><a href="ordered.html" class="codeexample lines[5,10,12-21]">ordered.html
</a></p>
-
You can highlight lines of code in the same manner, say you want like 18 to 20 in bold:
HTML:
-
-
<p><a href="ordered.html" class="codeexample lines[5,10,12-21] highlight[18-20]">ordered.html
</a></p>
-
Last but not least you can make the link clickable to show an IFRAME with the rendered output. Clicking the link again will remove the iframe. For this, just add a class called "dodisplay":
HTML:
-
-
<p><a href="ordered.html" class="codeexample dodisplay highlight[10,12,14-15]">ordered.html (click to show output)
</a></p>
-
The script is creative commons, and hopefully you'll find some extras to add. Enjoy.
Thursday, January 24th, 2008
Category: HTML
, JavaScript
, IE
Btw, if you want CSS rules to apply to unknown elements in IE, you just have to do document.createElement(elementName). This somehow lets the CSS engine know that elements with that name exist.
This was uttered by Sjoerd Visscher innocently on a Sam Ruby thread, and it sent ripples of "huh? really? How come I never know that!" through all of the experts.
This fact means that you the following will show up as red in IE 7:
HTML:
-
-
-
-
-
<style>blah { color: red; }
</style>
-
<script>document.createElement("blah")
</script>
-
</head>
-
-
<blah>Hello!</blah>
-
</body>
-
</html>
-
This is an example from John Resig as he discusses a HTML 5 shiv. You can see how a JavaScript shim can "implement" some of HTML 5 for us.
We have also gone down this route for some of the HTML 5 spec, and you can indeed do a lot with JavaScript. There are a couple of places where you kinda have to be in the browser to do the right thing.... but these are few and far between.
Sjoerd Visscher just blogged about this and told us how he found it out (back in 2002-ish!):
As far as I can remember we found out about this when we converted the first rendering of the XSL output from a lot of createElement calls to one innerHTML change for performance. This caused our custom elements to no longer be affected by CSS.
Wednesday, January 23rd, 2008
Category: HTML
While the community argued over X-UA-Compatible or X-IE-VERSION-FREEZE, depending on which side of the fence you sit, the W3C published two new and important documents:
Moments ago the joint effort of the W3C HTML WG and WHATWG resulted in publication of two documents in the W3C Technical Report space: HTML 5 and HTML 5 differences from HTML 4. I think I can safely say that the WHATWG community is very happy with the W3C publishing HTML 5 as a First Public Working Draft. Many thanks to all involved!
It is great to see this actually getting out there. It is very fun indeed to look at the new elements and think about how you would use the likes of <dialog>, <command>, <meter>, and finally being able to do things like input type="datetime|datetime-local|date|month|week|time|number|range|email|url".
It feels like semantics are being added in. The generality of div class="whatever" is all well and good, but for the very common situations, I am looking forward to using type="email" and having the browser take care of validation, and using my address book to pick through.
Friday, December 7th, 2007
Category: HTML
Lachlan Hunt has taken some time to walk us through some of the HTML 5 features that relate to new markup.
Work on HTML 5, which commenced in 2004, is currently being carried out in
a joint effort between the
W3C HTML
WG and
the WHATWG.
Many key players are participating in the W3C effort including representatives
from the four major browser vendors: Apple, Mozilla, Opera, and Microsoft;
and a range of other organizations and individuals with many diverse interests
and expertise.
Note that the
specification is still a work in progress and quite a long
way from completion. As such, it is possible that any feature discussed in
this article may change in the future. This article is intended to provide
a brief introduction to some of the major features as they are in the current
draft.
Take a look at the structure of HTML docs to come. No more div-hell:

Bloggers will be able to use the new article tag:
HTML:
-
-
<article id="comment-2">
-
<header>
-
<h4><a href="#comment-2" rel="bookmark">Comment #2
</a>
-
by
<a href="http://example.com/">Jack O'Niell
</a></h4>
-
<p><time datetime="2007-08-29T13:58Z">August 29th, 2007 at 13:58
</time>
-
</p></header>
-
<p>That's another great article!
</p>
-
</article>
-
And in general, Lachlan walks through how the pieces work together, including the video and audio tags.
Tuesday, November 13th, 2007
Category: HTML
, JavaScript
, Safari
WebKit keeps on trucking and has added support for the HTML 5 media tags such as <video> and <audio>.
You can add video to a page as easily as:
HTML:
-
-
<video src="sample.mov" autoplay></video>
-
That is a lot cleaner than the mess of embed/object/JavaScript wrappers that we have today. Also, there is nice scripting support so you can play/pause a video:
HTML:
-
-
-
function playPause() {
-
var myVideo = document.getElementsByTagName('video')[0];
-
if (myVideo.paused)
-
myVideo.play();
-
else
-
myVideo.pause();
-
}
-
</script>
-
<input type=button onclick="playPause()" value="Play/Pause"/>
-
You can also tie into events:
JAVASCRIPT:
-
-
myVideo.addEventListener('ended', function () {
-
alert('video playback finished')
-
} );
-
and programatically do your thing:
JAVASCRIPT:
-
-
new Audio("song.mp3").play();
-
One key issue has always been the codec game and royalties to mpeg.
Wednesday, October 24th, 2007
Category: HTML
, Gears
Dimitri Glazkov took a look at the HTML 5 SQL Storage API which WebKit just implemented and put together a Gears wrapper.
As an example he has Stickies running on Firefox with Gears.
The bridge is very simple indeed. Just take a peek at the code.
The major note here is that the current draft HTML 5 spec has the SQL API as an asynchronous one, whereas Gears has a synchronous API. In my experience, people prefer synchronous here, and Adobe AIR has a new synchronous API that they just released with the latest beta. I would love to see the HTML 5 spec contain a synchronous version too.
Friday, October 19th, 2007
Category: HTML
, Tip
I had never thought to use relative URLs that are just relative to the protocol scheme as Ned Batchelder explains in his post on Http-https transitions and relative URLs.
HTML:
-
-
<img src='//fast.cdn.net/pix/smiley.jpg' />
-
Who knew.
1.8 rating from 123 votes
Wednesday, August 22nd, 2007
Category: HTML