1. color correction for images in Firefox 3.5

    Back in Firefox 3, we introduced support for color profiles in tagged images, but it was disabled by default. In Firefox 3.5 we were able to make the color correction process about 5x faster than it was in Firefox 3 so we’ve enabled support for color correction for tagged images.

    Most images on the web are untagged. If you don’t know the difference between tagged images and untagged images the odds are good are you won’t notice this change. However, we suggest that you read on to learn about what it might mean for you if you want to include them and how future Firefox releases might change the interactions between CSS colors and images.

    What’s a color profile?

    People who spend a lot of time taking photographs or any kind of high-resolution color printing will understand that many output devices – LCDs, CRTs, paper etc – all have very different interpretations of what various colors mean. For example, uncorrected red will look very different on an LCD vs. a CRT. You can see this if you set up two very different monitors next to each other and the operating system doesn’t do color correction – colors will look more washed out in one of them vs. the other.

    JPG and PNG images both have support for color profiles. These color profiles allow Firefox to take colors in the image and translate them into colors that are independent of any particular device.

    While images contain color profiles it’s also important to note that output devices like monitors also have color profiles. As an example an output device may be better at displaying reds than blues. When you’re getting ready to show something that’s “red” on that device it might need to be converted from the neutral #ff0000 value to #f40301 in order to show up as red on the screen.

    What this means is that there are actually two conversions that take place with color profiles. The first is to take the original color information in the image and, using the color profile, convert it into a device-independent color space. Then once it’s in that independent space you convert it again using the output device’s color profile to get it ready to display on the output device.

    So what about CSS colors?

    It’s important to understand how color profiles work and how they are converted to properly understand how CSS interacts with these color spaces.

    In Firefox 3.5 we consider CSS colors to already be in the device output’s color space. Another way of saying this is that CSS colors are not in the neutral color space and are not converted into the output device like tagged images are.

    What this means is that if you have a tagged image where a color is expected to match the CSS that’s right next to it, it won’t. Or at least it’s likely that it won’t on some output device – maybe not the one that you happen to be using for development. Remember that different output devices have different color profiles. Here’s an example of what that looks like:

    In Firefox 3, this will look like one contiguous block of purple. In Firefox 3.5 and Safari you will notice that there’s a purple box within a purple box (unless your system profile is sRGB.) This is because the image is color corrected while the surrounding CSS is not.

    This is where the statement about the future comes in. In a future release of Firefox we are likely to make it possible for people to turn on color correction for tagged images and CSS. You can test this setting today by changing the pref listed on the page on color correction on the Mozilla Developer Center to “Full color management.” In that case untagged images should continue to work as we will be rendering both CSS and untagged images in the sRGB color space.

    Image support and tools

    PNG’s can be tagged in three different ways. First they can have an iCCP chunk that contains the associated ICC profile. Second they can be explicitly tagged as sRGB using a sRGB chunk. Finally, they can contain gAMA and cHRM chunks that describe the image’s gamma and chromaticies. Using any of thse methods will cause Firefox to color correct the image.

    You can remove all of the color correction chunks resulting in an untagged image using pngcrush:

    pngcrush -rem gAMA -rem cHRM -rem iCCP -rem sRGB infile.png outfile.png

    Alternatively, you can use TweakPNG and delete the gAMA, cHRM, iCCP and sRGB chunks by hand.

  2. an update on open video codecs and quality

    Two days ago we posted a comparison by Greg Maxwell of low and medium resolution YouTube videos vs. Theora counterparts at the same bit rates. The result in that test was that Theora did much better at the low bit rate and more or less the same at the slightly higher bit rate. The conclusion being that Theora is perfectly appropriate for a site like YouTube.

    Now Maik Merten has done the same with videos at HD resolution, comparing videos encoded by YouTube and a video encoded with the new Theora encoder at a managed bitrate. The results? Go have a look at the images in the post. Tell us if you can honestly see a major difference. We can’t.

    H.264
    Theora

  3. audio player – HTML5 style

    Last week we featured a demo from Alistair MacDonald (@F1LT3R) where he showed how to animate SVG with Canvas and a bunch of free tools. This week he has another demo for us that shows how you can use the new audio element in Firefox 3.5 with some canvas and JS to build a nice-looking audio player.

    But what’s really interesting about this demo is not so much that it plays audio – lots of people have built audio players – but how it works. If you look at the source code for the page what you’ll find looks something like this:

    <div id="jai">
      <canvas id="jai-transport" width="320" height="20"></canvas>
      <ul class="playlist">
        <li>
          <a href="@F1LT3R - Cryogenic Unrest.ogg">
            F1LT3R - Cryogenic Unrest
          </a>
          <audio src="@F1LT3R - Cryogenic Unrest.ogg"/>.
        <li>
          <a href="@F1LT3R - Ghosts in HyperSpace.ogg">
            F1LT3R - Ghosts in HyperSpace
          </a>
          <audio src="@F1LT3R - Ghosts in HyperSpace.ogg"/>.       
      </ul>    
    </div>
    (The actual list has fallbacks and is more compact – cleaned up here for easier reading.)

    That’s right – the player above is just a simple HTML unordered list that happens to include audio elements and is styled with CSS. You’ll notice that if you right click on one of them that it has all the usual items – save as, bookmark this link, copy this link location, etc. You can even poke at it with Firebug.

    The JavaScript driver that Al has written will look for a <div> element with the jai ID and then look for any audio elements that are inside it. It then will draw the playback interface in the canvas at the top of the list. The playback interface is built with simple JS canvas calls and an SVG-derived font.

    Using this driver it’s super-easy to add an audio player to any web site by just defining a canvas and a list. Much like what we’ve seen on a lot of the web with the rise of useful libraries like jQuery, this library can add additional value to easily-defined markup. Another win for HTML5 and the library model.

    Al has a much larger write-up on the same page as the demo. If you haven’t read through it you should now.

    (Also? Al wrote the music himself. So awesome.)

  4. better security and performance with native JSON

    The JavaScript Object Notation (JSON) mechanism for representing data has rapidly become an indispensable part of the web developer’s toolkit, allowing JavaScript applications to obtain and parse data intuitively, within scripts, with lightweight data encapsulation. Firefox 3.5 includes support for JSON natively by exposing a new primitive — window.JSON — to the top level object.

    Native “out of the box” support for JSON comes to the web courtesy of the ECMAScript 5th Edition (PDF link to specification), other aspects of which will also be supported by Firefox 3.5. Presently, native JSON is supported by Firefox 3.5 and IE8, with a strong likelihood of other browsers supporting it soon as well.

    Native JSON support has two advantages:

    1. Safety. Simply using eval to evaluate expressions returned as strings raises security issues. Also, the native JSON primitive can only work with data. It can’t be used to parse objects with method calls; attempting to do so returns an error.
    2. Performance. Parsing JSON safely, using third-party scripts and libraries, is likely to be slower than native JSON parsing within the browser.

    Let’s look at some examples.

    A JSON API for search results might look like this:

    /* 
    Assume that you obtained var data
    as a string from a server
    For convenience we display this search
    result on separate lines
    */
     
    var data = ' { "responseData":
    {"results": [
        {
            "SafeSearch":"true",
            "url":"http://www.arunranga.com/i.jpg",
        },
        {
            "SafeSearch":"false",
    	 "url":"http://www.badarunranga.com/evil.jpg",
        }
    ]}}';

    Such a resource could be returned by a simple HTTP GET request using a RESTful API.

    Using native JSON, you could do something like this:

    /* 
     Obtain a handle to the above JSON resource
     This is best and most conveniently done
     via third-party libraries that support native JSON
    */
     
    if (window.JSON) {
        var searchObj = JSON.parse(data);
        for (var i=0; i++; i < searchObj.responseData.results.length) {
            if (searchObj.responseData.results[i].SafeSearch) {
                var img = new Image();
                img.src = searchObj.responseData.results[i].url;
                // ... Insert image into DOM ...
        }
    }

    You can also stringify the object back to the string:

    // Back to where we started from
     
    var data = JSON.stringify(searchObj);
     
    // data now holds the string we started with

    Of course, to really enable the power of JSON, you’ll want to retrieve JSON resources from different domains, via callback mechanisms like JSONP. Many web developers are unlikely to use the JSON primitive directly. Rather, they’ll use them within libraries such as Dojo and jQuery. These libraries allow for the retrieval and direct parsing of JSON resources from different domains, and add a great deal of syntactic sugar to the process of callbacks and DOM insertions.

    The native JSON primitive works with the popular json2.js library (which correctly detects if native JSON is enabled), so developers can seamlessly use JSON parsing on browsers that don’t support native JSON. As of this writing, Dojo and jQuery have committed to supporting native JSON:

  5. 3D transforms in Firefox 3.5 – the isocube

    This demo was created by Zachary Johnson, a Minneapolis, MN based web developer who has also authored a jQuery plugin for animated “3D” rotation.

    I’d like to show an example of a visual effect that can be accomplished using the new -moz-transform CSS transformation property that is available in the Firefox 3.5 browser. I was very excited to see this feature added to Firefox because I knew it would allow me to produce a faux-3D isometric effect, also sometimes called 2.5D. I created a demo where HTML content is mapped onto the faces of a “3D” isometric cube:

    The -moz-transform property can take a list of CSS transform functions including rotate, scale, skew, and translate. Or, multiple transformations can be done simultaneously using a single 2D affine transformation matrix. Because all of the CSS transformation functions work in two dimensions, true 3D transformations with perspective projection cannot yet be accomplished. In this demo, I use the rotate and skew transformation functions in order to create the isometric effect.

    First, I define a container div for the cube, and then a square div for the top, left, and right faces of the cube.

    <div class="cube">
        <div class="face top">
        </div>
        <div class="face left">
        </div>
        <div class="face right">
        </div>
    </div>
    .cube {
        position: absolute;
    }
     
    .face {
        position: absolute;
        width: 200px;
        height: 200px;
    }

    Without getting too wrapped up in isometric projection math, we have to rotate and skew the cube faces in order to turn each square div into a parallelogram where the angles of the vertices are 60° or 120°. Here are what those transformations look like using the new -moz-transform CSS property:

    .top {
        -moz-transform: rotate(-45deg) skew(15deg, 15deg);
    }
     
    .left {
        -moz-transform: rotate(15deg) skew(15deg, 15deg);
    }
     
    .right {
        -moz-transform: rotate(-15deg) skew(-15deg, -15deg);
    }

    Now all that is left to do is to use absolute positioning to connect each transformed div in order to form the faces of the isometric cube. You can use matrix math to do this, or you could just move the faces around until they line up and it looks right.

    To add to the 3D effect, I’ve shaded the isometric cube by assigning different colors to the faces. I also gave the cube a shadow. You can see that the shadow is basically just a copy of the top face of the cube moved down to the bottom left, and then I gave the shadow div a black background color and set opacity: 0.5; in the CSS to make it filter over the page background.

    Any HTML, such as the text and form buttons in this example, can be put inside the div for any face of the cube. It will be translated into the correct perspective. Christopher Blizzard gave me the idea to throw video onto one side of the cube using the new HTML5 video tag now supported in Firefox 3.5. As you can see, it works great.

    Finally, by making a copy of the cube markup and using two more of the CSS transformation functions, I was able to create a second cube. I made the cube 50% as big using a scale(0.5) transformation, and I moved it into place by using translate(600px, 400px).

    I hope you found this demo to be interesting and that it opened up your mind to some exciting possibilities that Firefox 3.5 CSS transformations bring to the web.

    CSS transformations are also supported by Safari 3.1+ and Chrome using the -webkit-transform CSS property.

  6. a short introduction to media queries in Firefox 3.5

    This post is by Eric Shepherd, who leads Mozilla’s documentation project at the Mozilla Developer Center.

    In this day and age, it’s important for web content to support rendering on an increasingly wide variety of devices. Not only do users expect to use your content on their home computer, or read it printed on paper, but they want to use it on handheld devices, cell phones, and assorted other gadgets that have distinct capabilities, both in terms of performance and in terms of display fidelity.

    CSS 2 introduced the notion of media types, which allow you to specify different style rules based on what type of device the content is being rendered onto. For example, you can include a specific style sheet when your content is being rendered for printing like this:

    <link rel="stylesheet" media="print" href="print.css">

    This was a good first step; however, this doesn’t provide the ability to fine-tune the rendering of your content based on things such as device resolution, aspect ratio, or whether the content is being viewed in portrait or landscape orientation.

    Firefox 3.5 supports media queries — a new feature of CSS 3 — which make it possible to define much more precisely what styles to apply under what circumstances.

    This works by establishing queries that look at the values of various media features. There are a large number of these, including color depth, rendering area width and height, pixel resolution, whether or not the display is color, and so forth. You can find a complete list in the Mozilla Developer Center article on media queries.

    Media queries are quite powerful, but very easy to use. Take a look at the example web page I put together for this article.

    The example page uses two style sheets, which are specified using the following rules:

    <link rel="stylesheet" media="all and (orientation:portrait)"
     href="portrait.css">

    This one uses the media query all and (orientation:portrait) to indicate that the portrait.css style sheet should be used if the content is being rendered in a display area (such as the window in Firefox) is taller than it is wide.

    <link rel="stylesheet" media="all and (orientation:landscape)"
     href="landscape.css">

    This one specifies that the landscape.css style sheet should be applied when the content is being rendered on a surface that is wider than it is tall.

    What’s very cool about media queries is that they are evaluated every time the display mode changes; for example, if you open the example page and start resizing the window, you’ll find that when the window is wider than it is tall (i.e., it’s in landscape orientation), the toolbar is located on the left side of the page.

    When you resize the window so that it is in portrait orientation, the toolbar moves to the top of the window. This is done live while you’re resizing the window.

    If you look inside the landscape.css file, you’ll find that there are some media queries used there, as well, that override the style of the <body> element based on the width of the window. By default, the body text is 14 pixels tall.

    @media all and (min-width: 600px) {
      body {
        font-size: 16px;
      }
    }

    However, this media query indicates that if the window is at least 600 pixels wide, the font size for the body text should be increased to 16 pixels.

    @media all and (min-width: 700px) {
      body {
        font-size: 20px;
      }
    }

    Similarly, this media query makes the body’s font size 20 pixels when the window reaches at least 700 pixels wide. And another, similar media query makes the font even larger when the window is at least 800 pixels wide.

    So as you resize the window, you’ll see that not only does Firefox automatically switch between the portrait.css and landscape.css style sheets as the window’s width changes, but while rendering using the landscape.css style sheet, the styles change based on exactly how wide the window is, too.

    Another great use for this is to adjust the number of columns your content is displayed in based on the width of the display area.

    Media queries are currently supported by Firefox 3.5, Safari 3, and Opera 7 and later, with successive versions often adding support for additional media features.

    You can get details about which media features Firefox supports in the MDC article on media queries. Opera 9.5′s media features support is outlined near the bottom of this article. I wasn’t able to find specifics on WebKit’s media queries support.

    Media queries offer a great way to improve how your content looks on a variety of devices; using appropriate queries, you can render differently based on screen size, resolution, and more, thereby optimizing your content no matter how the user is accessing it.

  7. open video codecs and quality

    This is a re-post (with permission) of a post that Greg Maxwell wrote in response to a comment by Chris DiBona from Google on a whatwg mailing list. The codecs being discussed are the same ones we’ll be including in Firefox 3.5 and are also the same codecs that Mozilla, Wikipedia and others have been investing in.

    Recent developer nightlies of Google Chrome support these codecs and a future version of Opera will also support them. Theora and Vorbis also work in Safari if you install the Xiph Qt component. We’re quickly reaching the point where all modern browsers support these open codecs with full support for the video tag.

    You’ll note that Greg’s post doesn’t have the tone of a marketing document – it’s not meant to. Nor is this a comparison against HD-sized, high-bitrate video. Instead it’s an attempt to give an honest comparison of how the open codecs fare against commonly-used formats and sizes used on the world’s largest video site. I think you’ll agree with Greg’s conclusions at the bottom of the document, especially with audio where Vorbis really shines.

    Greg’s post follows.

    Purpose

    On Jun 13th 2009 Chris DiBona of Google made a remarkable claim on the WhatWG mailing list:

    “If [youtube] were to switch to theora and maintain even a semblance of the current youtube quality it would take up most available bandwidth across the Internet.”

    Unfortunately, open video formats have been subjected to FUD so frequently that people are willing to believe bold claims like these without demanding substantiation.

    In this comparison I will demonstrate that this claim was unfair and unreasonable. Using a simple test case I show that Theora is competitive and even superior to some of the files that Google is distributing today on YouTube.

    Theora isn’t the most efficient video codec available right now. But it is by no means bad, and it is substantially better than many other widely used options. By conventional criteria Theora is competitive. It also has the substantial advantage of being unencumbered, reasonable in computational complexity, and entirely open source. People are often confused by the correct observation that Theora doesn’t provide the state of the art in bitrate vs quality, and take that to mean that Theora does poorly when in reality it does quite well. Also, the Theora encoder has improved a lot lately so some older problems no longer apply.

    While different files may produce different results, the allegation made on WhatWG was so expansive that I believe a simple comparison can reliably demonstrate its falsehood.

    I do not believe Chris intended to deceive anyone, only that he is a victim of the same outdated and/or simply inaccurate information that has fooled many others. Automotive enthusiasts may make a big deal about a 5 horsepower difference between two cars, but these kinds of raw performance differences are not relevant to most car buyers nor are they even the most important criteria to people who race. Likewise, videophiles nitpick the quality of compression formats and this nitpicking is important for the advancement of the art. But I believe that people are mistaking these kinds of small differences for something which is relevant to their own codec selection.

    Results

    A 499kbit/sec H.264+AAC output and a 327kbit/sec H.263(Sorensen Spark)+MP3 output were available via the download service. The YouTube-encoded files are available on the YouTube site. Because the files on YouTube may change and the web player does not disclose the underlying bitrate, I have made the two encoded files available.

    ~499kbit/sec comparison

    YouTube

    Download (H.264+AAC; 17MiB)

    Ogg/Theora+Vorbis

    Download / Watch (Ogg/Theora+Vorbis; 17MiB)

    ~327kbit/sec comparison

    YouTube

    Download (H.263+MP3; 12MiB)

    Ogg/Theora+Vorbis

    Download / Watch (Ogg/Theora+Vorbis; 12MiB)

    A slightly lower bitrate was used for the Theora+Vorbis test cases to avoid any question of quality improvement resulting from larger outputs.
    For a fair comparison you must compare the audio as well. Even without audio differences, still image comparisons are a poor proxy for video quality.
    I provided this random frame still image comparison only because I expect that people will not bother watching the examples without evidence that the results are interesting.

    Methodology

    In order to avoid any possible bias in the selection of H.264 encoders and encoding options, and to maximize the relevance for this particular issue, I’ve used YouTube itself as the H.264 encoder. This is less than ideal because YouTube does not accept lossless input, but it does accept arbitrarily high bitrate inputs.

    I utilized the Blender Foundation’s Big Buck Bunny as my test case because of its clear licensing status, because it’s a real world test case, and because I have it available in a lossless format. I am not aware of any reason why this particular clip would favor either Theora or H.264.

    I chose to use a test case with a soundtrack because most real usage has sound. No one implements HTML5 video without audio, and no one is implementing either of Theora or Vorbis without the other. Vorbis’s state-of-the-art performance is a contributor to the overall Ogg/Theora+Vorbis solution.

    • Obtain the lossless 640×360 Big Buck Bunny source PNGs and FLACs from media.xiph.org.
    • Resample the images to 480×270 using ImageMagick’s convert utility.
    • Use gstreamer’s jpegenc, produce a quality=100 mjpeg + PCM audio stream. The result is around 1.5Gbytes with a bitrate of around 20Mbit/sec.
    • Truncate the file to fit under the YouTube 1Gbyte limit, resulting in input_mjpeg.avi (706MiB).
    • Upload the file to YouTube and wait for it to transcode.
    • Download the FLV and H.264 files produced by YouTube using one of the many web downloading services. (I used keepvid)
    • Using libtheora 1.1a2 and Vorbis aoTuv 5.7 produce a file of comparable bitrate to the youtube 499kbit/sec from the same file uploaded to YouTube (input_mjpeg.avi).
    • Resample the file uploaded to YouTube to 400×226.
    • Using libtheora 1.1a2 and Vorbis aoTuv 5.7 produce a file of comparable bitrate to the youtube 327kbit/sec from the 400×226 downsampled copy of input_mjpeg.avi.

    I later discovered that YouTube sometimes offers additional sizes. I tried the youtube-dl utility and it indicated that these other sizes were not available for my file. Otherwise I would have also included them in this comparison.

    A keyframe interval of 250 frames was used for the Theora encoding. The theora 1.1a2 encoder software used is available from theora.org. The Vorbis encoder used is available from the aoTuV website. No software modifications were performed.

    My conclusions

    It can be difficult to compare video at low bitrates, and even YouTube’s higher bitrate option is not high enough to achieve good quality. The primary challenge is that all files at these rates will have problems, so the reviewer is often forced to decide which of two entirely distinct flaws is worse. Sometimes people come to different conclusions.

    That said, I believe that the Theora+Vorbis results are substantially better than the YouTube 327kbit/sec. Several other people have expressed the same view to me, and I expect you’ll also reach the same conclusion. This is unsurprising since we’ve been telling people that Theora is better than H.263, especially at lower bitrates, for some time now and YouTube only uses a subset of H.263.

    The low bitrate case is also helped by Vorbis’ considerable superiority over MP3. For example, the crickets at the beginning are inaudible in the low rate YouTube clip but sound fine in the Ogg/Theora+Vorbis version.

    In the case of the 499kbit/sec H.264 I believe that under careful comparison many people would prefer the H.264 video. However, the difference is not especially great. I expect that most casual users would be unlikely to express a preference or complain about quality if one was substituted for another and I’ve had several people perform a casual comparison of the files and express indifference. Since Theora+Vorbis is providing such comparable results, I think I can confidently state that reports of the internet’s impending demise are greatly exaggerated.

    Of course, YouTube may be using an inferior processing chain, or encoding options which trade off quality for some other desirable characteristic (like better seeking granularity, encoding speed, or a specific rate control pattern). But even if they are, we can conclude that adopting an an open unencumbered format in addition to or instead of their current offerings would not cause problems on the basis of quality or bitrate.

    But please— see and hear for yourself.

  8. web fonts and css features – a simple demonstration

    This post is from Laurent Jouanneau, who was kind enough to build a very simple but elegant demonstration of how to use web fonts and some of the new CSS features in Firefox 3.5.

    View the Demo in Firefox 3.5
    font_shadow_radius

    Shadows and round corners

    First, we set some style properties on the toolbar:

    -moz-border-radius

    -moz-border-radius:10px 0px 10px 0px;

    This indicates that top left and bottom right border corner should be round with a radius of 10 pixels.

    -moz-box-shadow

    -moz-box-shadow: #9BD1DE 5px 5px 6px;

    This indicates that a shadow should be drawn under the div, with an offset of 5 pixels to the right and the bottom, and with a blur radius of 6 pixels.

    Second, the buttons. We still use a border-radius property. But we use also a box-shadow property which changes depending of the state of the button. In the normal state, there is a shadow outside the button. When the mouse hovers over it (the hover state), the shadow is changed to be inside the button using the inset CSS property. We do the same thing when we click on the button (the active state), but we also make the shadow is bigger and darker.

    #superbox button {
        -moz-border-radius: 5px;
        -moz-box-shadow: #000 0px 0px 8px;
    }
     
    #superbox button:hover {
        -moz-box-shadow: inset #989896 0 0 3px;
        text-shadow: red 0px 0px 8px;
    }
     
    #superbox button:active {
        -moz-box-shadow: inset #1C1C1C 0 0 5px;
    }

    You can also see that we add a red shadow under the text of the button when the mouse hovers over it using the text-shadow property.

    Web fonts

    Each button is rendered with its own font, declared using @font-face. Example:

    @font-face {
        font-family: Brock Script;
        src: url("BrockScript.ttf");
        font-style: normal;
        font-weight: normal;
    }

    With the font-family property, we indicate a name for our font. The src indicates the url of the downloadable font.

    Once we’ve defined the @font-face property we can use it in the CSS for one of the buttons:

    .first {
        font-family: Brock Script;
    }

    When you declare the font with @font-face, and then use the font in CSS, the browser will automatically download and render using that font. The browser won’t download fonts you don’t use, so it’s safe to include descriptions of fonts from a common CSS file that might not be used in the page that you’re currently displaying.

    In the demonstration there’s also a small amount of script connected to each of the buttons that changes the class of the blue box to use the downloaded font for that button showing that you can update fonts on the fly as well.

    With these relatively simple techniques we can have beautiful buttons without having to use a bitmap image.

    Note: these fonts can be downloaded from fontsquirrel.com : Brock-Script (created by Dieter Steffmann), Sniglet (created by The League of Moveable Type, under the licence CC-by-sa) and Quick End Jerk (created by Vic Fieger).

  9. DOM selectors API in Firefox 3.5

    The Selectors API recommendation, published by the W3C, is a relatively new effort that gives JavaScript developers the ability to find DOM elements on a page using CSS selectors. This single API takes the complicated process of traversing and selecting elements from the DOM and unifies it under a simple unified interface.

    Out of all the recent work to come out of the standards process this is one of the better-supported efforts across all browsers: Usable today in Internet Explorer 8, Chrome, and Safari and arriving in Firefox 3.5 and Opera 10.

    Using querySelectorAll

    The Selectors API provides two methods on all DOM documents, elements, and fragments: querySelector and querySelectorAll. The methods work virtually identically, they both accept a CSS selector and return the resulting DOM elements (the exception being that querySelector only returns the first element).

    For example, given the following HTML snippet:

    <div id="id" class="class">
        <p>First paragraph.</p>
        <p>Second paragraph.</p>
    </div>

    We would be able to use querySelectorAll to make the background of all the paragraphs, inside the div with the ID of ‘id’, red.

    var p = document.querySelectorAll("#id p");
    for ( var i = 0; i < p.length; i++ ) {
        p[i].style.backgroundColor = "red";
    }

    Or we could find the first child paragraph of a div that has a class of ‘class’ and give it a class name of ‘first’.

    document.querySelector("div.class > p:first-child")
        .className = "first";

    Normally these types of traversals would be very tedious in long-form JavaScript/DOM code, taking up multiple lines and queries each.

    While the actual use of the Selectors API methods is relatively simple (each taking a single argument) the challenging part comes in when choosing which CSS selectors to use. The Selectors API taps in to the native CSS selectors provided by the browser, for use in styling elements with CSS. For most browsers (Firefox, Safari, Chrome, and Opera) this means that you have access to the full gamut of CSS 3 selectors. Internet Explorer 8 provides a more-limited subset that encompasses CSS 2 selectors (which are still terribly useful).

    The biggest hurdle, for most new users to the Selectors API, is determining which CSS selectors are appropriate for selecting the elements that you desire – especially since most developers who write cross-browser code only have significant experience with a limited subset of fully-working CSS 1 selectors.

    While the CSS 2 and CSS 3 selector specifications can serve as a good start for learning more about what’s available to you there also exist a number of useful guides for learning more:

    Implementations in the Wild

    The most compelling use case of the Selectors API is not its direct use by web developers, but its use by 3rd-party libraries that already provide DOM CSS selector functionality. The trickiest problem towards adopting the use of the Selectors API, today, is that it isn’t available in all browsers that users develop for (this includes IE 6, IE 7 and Firefox 3). Thus, until those browsers are no longer used, we must use some intermediary utility to recreate the full DOM CSS selector experience.

    Thankfully, a number of libraries already exist that provide an API compatible with the Selectors API (in fact, much of the inspiration for the Selectors API comes from the existence of these libraries in the first place). Additionally, many of these implementations already use the Selectors API behind the scenes. This means that you can use using DOM CSS selectors in all browsers that you support AND get the benefit of faster performance from the native Selectors API implementation, with no work to you.

    Some existing implementations that gracefully use the new Selectors API are:

    It’s important to emphasize the large leap in performance that you’ll gain from using this new API (in comparison to the traditional mix of DOM and JavaScript that you must employ). You can really see the difference when you look at the improvement that occurred when JavaScript libraries began to implement the new Selectors API.

    When some tests were run previously the results were as follows:

    You can see the dramatic increase in performance that occurred once the libraries began using the native Selectors API implementations – it’s quite likely that this performance increase will happen in your applications, as well.

    Test Suite

    To coincide with the definition of the Selectors API specification a Selectors API test suite was created by John Resig of Mozilla. This test suite can be used as a way to determine the quality of the respective Selectors API implementations in the major browsers.

    The current results for the browsers that support the API are:

    • Firefox 3.5: 99.3%
    • Safari 4: 99.3%
    • Chrome 2: 99.3%
    • Opera 10b1: 97.5%
    • Internet Explorer 8: 47.4%

    Internet Explorer 8, as mentioned before, is missing most CSS 3 selectors – thus failing most of the associated tests.

    As it stands, the Selectors API should serve as a simple, and fast, way of selecting DOM elements on a page. It’s already benefiting those who use JavaScript libraries that provide similar functionality so feel free to dig in today and give the API a try.

  10. geolocation with open street maps

    This demo was created by René-Luc D’Hont. He created this demo for the 35 days project with open source software and open data from various projects. His company, 3Liz, specializes in open source GIS application development.

    Three days ago we had a post from Doug Turner describing how Geolocation works in Firefox 3.5. René-Luc has taken the geolocation functionality in Firefox 3.5 and blended it together with data from OpenStreetMap and a few other sources of free data. You can try the demo below. Don’t forget to click the Share Location button in the drop down when it appears on the site.

    Assuming that it was able to find your location, you should see where you are with a red marker. A blue circle surrounds the red marker indicating the accuracy of your location information. Note that since this information is based on a combination of your IP address and possibly local WiFi access points, its accuracy can vary.

    This demo also tries to pull in information from other sources about your local area. Each set of information is shown as a layer. These layers are:

    • The base layer is the map itself, provided by OpenStreetMap. OpenStreetMap is a project to create and provide free geographic data, such as street maps, to anyone who wants them. Much like Wikipedia, it’s possible for anyone to edit the maps and add their own information.
    • The next layer is based on articles in Wikipedia. In some articles, like Mountain View or Montpellier, you can find coordinates. GeoNames provides a web service to query Wikipedia’s articles by location. With this demo you can discover Wikipedia articles about things and places around you.
    • The last layer is based on GeoNames. GeoNames is a geographical database covering all countries and contains over eight million placenames. In this demo you can see things from the GeoNames database like cities, villages, lakes, parks, or even hotels.

    The map and layers are built using OpenLayers, a free JavaScript library that you can use to put a dynamic map on any web page.

    Resources

    We’ve also included a couple more screenshots of places that have data already loaded.

    geolocation-2

    geolocation-3