Mozilla

Feature Articles

Sort by:

View:

  1. taming long words with word-wrap

    This post is from Les Orchard, who works on Mozilla’s web development team.

    Web browsers have a long history of sharing features between them. The word-wrap CSS property is a feature that originally came from Microsoft and is included in CSS3.

    Now available in Firefox 3.5, this CSS property allows the browser to arbitrarily break up long words or strings of characters to fit within a given element.

    How is this helpful? Well, have you ever had to display an extremely long URL or block of data on a page? Sure, URL shortening services have helped, but the basic layout issue still remained.

    Consider the following URL using the data scheme:

    Presented in a <textarea>, this huge URL behaves well enough to at least not break the layout of this page. But, it’s not really handled all that gracefully beyond that. Most browsers don’t quite know what to do with the scrollbar, styling is a pain, and presenting the URL in an editable field isn’t really the intent here.

    Alternatively, you could stuff the URL into a <div> and slap an overflow: hidden style on it, like so:

    Again, the page layout isn’t broken, but now the URL is cut off. So, why not try an overflow: auto style instead?

    This will give you a scrollbar, at least:

    data:text/html;charset=utf-8;base64,Q29uZ3JhdHVsYXRpb25zISBZb3UndmUgZm91bmQgdGhlIGhpZGRlbiBtZXNzYWdlIQ0KDQpUbyBjbGFpbSB5b3VyIHByaXplLCB2aXNpdCBodHRwOi8vZ2V0ZmlyZWZveC5jb20gdG9kYXkhDQoNCkZyZWUgYnJvd3NlciBpbiBldmVyeSBib3ghDQo%3D

    But now, visitors to your page have to scroll to see the whole
    thing, and highlighting the text for copy & paste can be
    cumbersome.

    So, finally, here’s the word-wrap: break-word payoff:

    data:text/html;charset=utf-8;base64,Q29uZ3JhdHVsYXRpb25zISBZb3UndmUgZm91bmQgdGhlIGhpZGRlbiBtZXNzYWdlIQ0KDQpUbyBjbGFpbSB5b3VyIHByaXplLCB2aXNpdCBodHRwOi8vZ2V0ZmlyZWZveC5jb20gdG9kYXkhDQoNCkZyZWUgYnJvd3NlciBpbiBldmVyeSBib3ghDQo%3D
    word-wrap:
    normal
    break-word

    See the difference for yourself: Use the radio buttons above to switch between the values normal (the default) and break-word. The normal value will cause the URL to spill out of the containing <div>, possibly breaking the layout of this page.

    On the other hand, using word-wrap: break-word will allow the browser to coerce the text into the confines of the <div>, thus preserving your page layout and quite possibly your sanity.

  2. the script defer attribute

    This post is by Olivier Rochard. Olivier does research at Orange Labs in France.

    In HTML, the script element allows authors to include dynamic script in their documents. The defer attribute is boolean attribute that indicates how the script should be executed. If the defer attribute is present, then the script is executed when the page has finished parsing. The element is added to the end of the list of scripts that will execute when the document has finished parsing. Think about a FIFO processing queue : the first script element to be added to the queue will be the first script to be executed, then processing proceeds sequentially in the same order.

    There is one very good reason for using the defer attribute: performance. If you include a script element in your HTML page the script must be evaluated immediately while the page is being parsed. This means that objects have to be created, styles must be flushed, etc. This can make page loading slower. The defer attribute implies that the script has no side effects on the document as it’s being loaded and can safely be evaluated at the end of the page load.

    The defer attribute was first introduced in Internet Explorer 4, and added in the HTML 4 specification.

    A simple test.

    Here is a simple first test to see how the attribute works. The following lines are in the head element of a page:

    ‹script›
    	var test1 = "Test 1 : fail";
    ‹/script›
    ‹script defer›
      	console.log(test1);
    ‹/script›
    ‹script›
    	test1 = "Test 1 : pass";
    ‹/script›

    If the defer attribute for the script element is correctly implemented the browser will:

    1. Render the page.
    2. Execute the second script element after all the others.
    3. Display “Test 1 : pass” on the Firebug console.

    If the console displays “Test 1 : fail” it’s because the scripts are executed in the same order as in the source code.

    Note that the correct syntax for XHTML documents is:

    <script defer="defer"></script>

    A more advanced test

    This second test is a way to see how the feature works in a webpage with multiple script elements inserted:

    • Inline in the head and body elements
    • External via src attribute in head and body elements
    • With dynamic DOM insertion

    Here is partial source code of a webpage that tests how defer affects script loading and parsing order:

    ‹!doctype html›
    ‹html›
        ‹head›
            ‹title› Test 2 ‹/title›
            ‹script› var test2 = "Test 2 :\n\n"; ‹/script›
            ‹script› document.addEventListener("DOMContentLoaded",
                    function(){
                            test2 += "\tDOMContentLoaded\n";
                    }, false);
            ‹/script›
            ‹script defer› test2 += "\tInline HEAD deferred\n"; ‹/script›
            ‹script› test2 += "\tInline HEAD\n"; ‹/script›
            ‹script src="script1.js" defer›
                    // External HEAD deferred (script1.js) 
            ‹/script›
            ‹script src="script2.js"›
                    // External HEAD  (script2.js)
            ‹/script›
    	‹script›
                // Dynamic DOM insertion of a script (script3.js)
                head = document.getElementsByTagName('head')[0];
                script3 = document.createElement('script');
                script3.setAttribute('src', 'script3.js');
                head.appendChild(script3);
                // Dynamic DOM insertion of a deferred script (script4.js)
                script4 = document.createElement('script');
                script4.setAttribute('defer', 'defer');
                script4.setAttribute('src', 'script4.js');
                head.appendChild(script4);
    	‹/script›
    	‹script defer›
                // Deferred dynamic DOM insertion of a script (script5.js)
                head = document.getElementsByTagName('head')[0];
                script5 = document.createElement('script');
                script5.setAttribute('src', 'script5.js');
                head.appendChild(script5);
                // Deferred dynamic DOM insertion of a deferred script
                // (script6.js)
                script6 = document.createElement('script');
                script6.setAttribute('defer', 'defer');
                script6.setAttribute('src', 'script6.js');
                head.appendChild(script6);
    	‹/script›
        ‹/head›
        ‹body onload="test2 += '\tBody onLoad\n';"›
            ‹script defer› test2 += "\tInline BODY deferred\n"; ‹/script›
            ‹script› test2 += "\tInline BODY\n"; ‹/script›
     
    	... other body content ...
     
    		<a onclick="alert(test2);">Launch test 2</a>
     
    	... other body content ...
     
            ‹script src="script7.js" defer›
                    // External BODY deferred (script7.js)
            ‹/script›
            ‹script src="script8.js"›
                    // External BODY (script8.js)
            ‹/script›
        ‹/body›
    ‹/html›

    When you click on the “Launch test 2″ link in the document a pop-up appears with a list in it. This list shows the order of script elements loaded during the session.

    The test also displays the DOMContentLoaded and body.onload events when they are fired.

    If the defer attribute is correctly implemented in the browser, all the deferred lines should be near the bottom of the list.

    Results of the second test for each browser are below (deferred scripts are in green color) :

    • The defer attribute behavior in the Firefox 3.5 browser is correct:

      1. Inline HEAD
      2. External HEAD (script2.js)
      3. Dynamic DOM insertion of a script (script3.js)
      4. Inline BODY
      5. External BODY (script8.js)
      6. Inline HEAD deferred
      7. External HEAD deferred (script1.js)
      8. Dynamic DOM insertion of a deferred script (script4.js)
      9. Inline BODY deferred
      10. External BODY deferred (script7.js)
      11. Deferred dynamic DOM insertion of a script (script5.js)
      12. Deferred dynamic DOM insertion of a deferred script (script6.js)
      13. DOMContentLoaded
      14. Body onLoad
    • The defer attribute behavior in the IE 8 browser is erratic: the order is different at each reload :

      1. Inline HEAD
      2. External HEAD (script2.js)
      3. Inline BODY
      4. External BODY (script8.js)
      5. Dynamic DOM insertion of a script (script3.js)
      6. Dynamic DOM insertion of a deferred script (script4.js)
      7. Inline HEAD deferred
      8. External HEAD deferred (script1.js)
      9. Inline BODY deferred
      10. External BODY deferred (script7.js)
      11. Body onLoad
      12. Deferred dynamic DOM insertion of a script (script5.js)
      13. Deferred dynamic DOM insertion of a deferred script (script6.js)
    • The defer attribute behavior in a WebKit browser (Safari 4.0) is erratic : the order is different at each reload :

      1. Inline HEAD deferred
      2. Inline HEAD
      3. External HEAD deferred (script1.js)
      4. External HEAD (script2.js)
      5. Inline BODY deferred
      6. Inline BODY
      7. External BODY deferred (script7.js)
      8. Deferred dynamic DOM insertion of a script (script5.js)
      9. Dynamic DOM insertion of a deferred script (script4.js)
      10. Deferred dynamic DOM insertion of a deferred script (script6.js)
      11. Dynamic DOM insertion of a script (script3.js)
      12. External BODY (script8.js)
      13. DOMContentLoaded
      14. Body onLoad
    • The defer attribute behavior in the Opera 10.00 Beta browser:

      1. Inline HEAD deferred
      2. Inline HEAD
      3. External HEAD deferred (script1.js)
      4. External HEAD (script2.js)
      5. Dynamic DOM insertion of a script (script3.js)
      6. Dynamic DOM insertion of a deferred script (script4.js)
      7. Deferred dynamic DOM insertion of a script (script5.js)
      8. Deferred dynamic DOM insertion of a deferred script (script6.js)
      9. Inline BODY deferred
      10. Inline BODY
      11. External BODY deferred (script7.js)
      12. External BODY (script8.js)
      13. DOMContentLoaded
      14. Body onLoad

    We hope that this has been a useful introduction to how the defer attribute works in Firefox 3.5. The tests above will also help you predict behavior in other browsers as well.

    Resources

  3. saving data with localStorage

    This post was written by Jeff Balogh. Jeff works on Mozilla’s web development team.

    New in Firefox 3.5, localStorage is a part of the Web Storage specification. localStorage provides a simple Javascript API for persisting key-value pairs in the browser. It shouldn’t be confused with the SQL database storage proposal, which is a separate (and more contentious) part of the Web Storage spec. Key-value pairs could conceivably be stored in cookies, but you wouldn’t want to do that. Cookies are sent to the server with every request, presenting performance issues with large data sets and the potential for security problems, and you have to write your own interface for treating cookies like a database.

    Here’s a small demo that stores the content of a textarea in localStorage. You can change the text, open a new tab, and find your updated content. Or you can restart the browser and your text will still be there.


    The easiest way to use localStorage is to treat it like a regular object:

    >>> localStorage.foo = 'bar'
    >>> localStorage.foo
    "bar"
    >>> localStorage.length
    1
    >>> localStorage[0]
    "foo"
    >>> localStorage['foo']
    "bar"
    >>> delete localStorage['foo']
    >>> localStorage.length
    0
    >>> localStorage.not_set
    null

    There’s also a more wordy API for people who like that sort of thing:

    >>> localStorage.clear()
    >>> localStorage.setItem('foo', 'bar')
    >>> localStorage.getItem('foo')
    "bar"
    >>> localStorage.key(0)
    "foo"
    >>> localStorage.removeItem('foo')
    >>> localStorage.length
    0

    If you want to have a localStorage database mapped to the current session, you can use sessionStorage. It has the same interface as localStorage, but the lifetime of sessionStorage is limited to the current browser window. You can follow links around the site in the same window and sessionStorage will be maintained (going to different sites is fine too), but once that window is closed the database will be deleted. localStorage is for long-term storage, as the w3c spec instructs browsers to consider the data “potentially user-critical”.

    I was a tad disappointed when I found out that localStorage only supports storing strings, since I was hoping for something more structured. But with native JSON support it’s easy to create an object store on top of localStorage:

    Storage.prototype.setObject = function(key, value) {
        this.setItem(key, JSON.stringify(value));
    }
     
    Storage.prototype.getObject = function(key) {
        return JSON.parse(this.getItem(key));
    }

    localStorage databases are scoped to an HTML5 origin, basically the tuple (scheme, host, port). This means that the database is shared across all pages on the same domain, even concurrently by multiple browser tabs. However, a page connecting over http:// cannot see a database that was created during an https:// session.

    localStorage and sessionStorage are supported by Firefox 3.5, Safari 4.0, and IE8. You can find more compatibility details on quirksmode.org, including more detail on the storage event.

  4. new CSS3 properties in Firefox 3.5 – nth-*

    Firefox 3.5 supports several new CSS3 selectors. In this post we’ll talk about four of them: :nth-child, :nth-last-child, :nth-of-type and :nth-last-of-type.

    Each of these is called a Pseudo-class and can be used to apply styles to existing selectors. The best way to describe how this works is with some examples.

    :nth-child

    This pseudo-class lets you apply styles to groups of elements. The most common use case is to highlight odd or even items in a table:

    tr:nth-child(even)
    {
        background-color: #E8E8E8;
    }

    A live example (works in Firefox 3.5):

    Row 1
    Row 2
    Row 3
    Row 4

    But you can also use it to apply styles to groups of more than two using a special notation. The documentation for this rule is pretty obtuse but basically the “3” in the example splits the number of elements into groups of three and the “+1″ is the offset in that group. There are more examples in the spec as well.

    tr:nth-child(3n+1) {  background-color: red; }
    tr:nth-child(3n+2) {  background-color: green; }
    tr:nth-child(3n+3) {  background-color: blue; }

    A live example (works in Firefox 3.5):

    Row 1
    Row 2
    Row 3
    Row 4
    Row 5
    Row 6

    :nth-last-child

    The :nth-last-child pseudo-class works exactly like the :nth-child pseudo-class except that it counts elements in the opposite direction:

    tr:nth-last-child(3n+3) {  background-color: red; }
    tr:nth-last-child(3n+2) {  background-color: green; }
    tr:nth-last-child(3n+1) {  background-color: blue; }

    Example (works in Firefox 3.5):

    Row 1
    Row 2
    Row 3
    Row 4
    Row 5
    Row 6

    :nth-of-type

    The :nth-of-type pseudo-class uses the same kind of syntax as the other elements here but allows you to select based on element type.

    div:nth-of-type(odd) { border-color: red }
    div:nth-of-type(even) { border-color: blue }

    Example (works in Firefox 3.5):

    I should be red!
    I should be blue!

    :nth-last-of-type

    Much like :nth-last-child, :nth-last-of-type is the same as :nth-of-type except that it counts in the opposite direction.

    These four properties allow you to do interesting things with style and element groups and we hope that they make it easier to style your pages.

  5. opacity in Firefox 3.5

    This is a very short post, but it’s worth putting up because it shows how browser features go from a vendor-specific implementation to a fully supported standard.

    In Firefox 3.5 we no longer support the Mozilla-specific CSS property -moz-opacity. Developers wanting to set the opacity of an element should use the standard opacity property instead.

    We introduced the opacity property way back in Firefox 0.9 and -moz-opacity was deprecated. And with Firefox 3.5 we’ve finally removed it.

    A long road for a simple property, but it’s worth mentioning so people understand the time scale for these kinds of features and how they relate to standards.

  6. debugging painting with MozAfterPaint

    This was originally posted by Robert O’Callahan in the Mozilla web-tech blog. It’s an interesting feature in Firefox 3.5 and is worth repeating here as part of our 35 days effort.

    In addition, Thomas Robinson has created a very handy bookmarklet for debugging painting on a page you’ve loaded in the browser.

    Due to popular demand, we’ve created a very experimental API for Firefox 3.5 to fire an event every time content is repainted. The event is is called MozAfterPaint and is fired at the document, bubbling up to the window. The event offers two attributes, clientRects and boundingClientRect, which tell you what was repainted, using the same objects and coordinate system as the getClientRects and getBoundingClientRect methods.

    This is very useful for Firefox extensions and other “chrome” code that might be using the canvas.drawWindow method to capture the contents of windows. It might also be useful for tools like Firebug. But it’s also potentially useful for regular content, for example if you want to add some lightweight JS instrumentation to a page to measure what gets painted by Firefox, and when.

    Caveats:

    • This is Gecko-only. Do not use this for actual functionality on public Web pages – although I’m not sure why anyone would, so I don’t currently see this as a candidate for standardization.
    • For security reasons, regular Web content is only notified of repainting that occurred in its own document – repainting caused by IFRAMEs is not reported to untrusted listeners attached to the IFRAME’s ancestors. (Listeners added by “trusted” content such as Firefox chrome are notified of all repaints to the window, however.)
    • Currently the event might fire before the actual repainting happens. This shouldn’t matter much, and we’ll fix that at some point.
    • If your event handler does anything that triggers repainting, such as changing the style of an element, you will probably trigger an infinite loop. The browser should stay responsive but your machine will contribute to global warming.
    • Repainting of areas scrolled outside the viewport is reported, but repainting of areas scrolled outside overflow:auto elements and the like is not reported.
    • Repainting in windowed plugins (i.e. most plugins in Windows and GTK) is not reported.
  7. XHR progress and rich file upload feedback

    This demo is by Olli Pettay (smaug) with help from Austin King.

    A common limitation on the web today has been a rich file upload widget for web applications. Many sites use Flash or a desktop helper applications to improve the experience of uploading files.

    Firefox 3.5 bridges one of these gaps allowing a better progress indicator to be built. Many developers don’t realize that they can use Firefox’s File object (nsIDOMFile) and XMLHttpRequest together to accomplish file uploads. This demo will feature an upload widget that gives the kind of rich progress feedback that users have come to expect, as well as fast and easy multiple simultaneous file uploads.

    Progress Indicators

    It’s always a good idea to expose feedback that your application is hard at work for them, and when the current action is expected to finish. The two main types of progress feedback are:

    • indeterminate progress – some activity just happened
    • deterministic progress I’m 40% done, I’m 42% done… etc

    Deterministicsaidwhat? The Demo

    We’ve created a simple file upload / download page that demonstrates the progress bar:

    The demo is host at mozilla.pettay.fi and requires Firefox 3.5 beta4 or later. It demonstrates how to do multiple simultaneous file uploads without posting a form or leaving the current page. For each file upload / download we display the current speed, % complete, and bytes transmitted. We’ll go over a few key snippets of the code which are used in the screenshot above. Please click through the the demo and view source for the full code example.

    The page contains two HTML inputs, one type="file" and one type="button". The form is never actually submitted, instead we add an onclick handler to the button:

    <input type="file" id="file">
    <input type="button"
              onclick="startXHR();"
              value="Upload file using XHR">

    In the startXHR function, we create an XMLHttpRequest and add an event handler to the XHR request to listen for the new ‘progress’ event. With this ProgressEvent’s lengthComputable property, we will know if we are dealing with an indeterminate or deterministic progress. The object also gives us loaded and total bytes.

    var xhr = new XMLHttpRequest();
     
    xhr.onprogress = function(evt) {        
    if (evt.lengthComputable) {
        evt.target.curLoad = evt.loaded;
        evt.target.log.parentNode.parentNode.previousSibling.textContent =
            Number(evt.loaded/k).toFixed() + "/"+ Number(evt.total/k).toFixed() + "kB";
    }
    if (evt.lengthComputable) {
        var loaded = (evt.loaded / evt.total);
        if (loaded < 1) {
            var newW = loaded * width;
            if (newW < 10) newW = 10;
                evt.target.log.style.width = newW + "px";
            }
        }
    };

    Now we need some data to send. We grab the contents of the file directly from the input by id:

    var files = document.getElementById("file").files;
    if (files) {
       var file = files.item(0);
       xhr.sendAsBinary(file.getAsBinary());

    And the last step is to start the request:

    xhr.open("POST", "cgi-bin/posthandler.pl");
    xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
    xhr.sendAsBinary(file.getAsBinary());

    These methods would also work with xhr.upload.onprogress.

    Notice the use of the sendAsBinary method on the XMLHttpRequest object and getAsBinary on the File object. Starting with Firefox 3 you’ve been able to get at the contents of a file on the client side without form submission. This is quite useful for moving beyond the limitation of tranditional file input and form submissions. It is also part of an up and coming W3C standard for FileUpload.

    A related method that the nsIDOMFile provides is the getAsText method which returns a DOMString suitable for slicing, dicing, and displaying.

    Here is an example usage, not used by the demo:

    file.getAsText("utf8");

    So that’s the gist of the code. Check out the demo and view it’s source.

    Feedback In User Interfaces

    Exposing system feedback to users improves perceived performance. We
    can’t always determine how long something will take, so at a minimum we
    can show indeterminate progress.

    During file uploads and file downloads (assuming the server gives us Content-Length) we do indeed know the total number of bytes. Firefox 3.5’s Progress Events support adds a progress event so that we can show actual upload/download progress.

    Traditionally XMLHttpRequests were difficult to get deterministic progress back from. In theory, you could give it callbacks and watch for status code updates and textual message updates, but in practice they turn out to be not very useful. In the past, if a deterministic progress meter was important, you’d have to make a second XHR request to poll for progress.

    Enter Progress Events

    The W3C has a working draft for Progress Events 1.0 which we include in Firefox 3.5. Firefox has added a key new DOM ProgressEvent progress event, as well as the loadstart event. The other existing events included: error, abort and load.

    These same events are also available for uploads and downloads. The progress event gives us the following properties:

    • lengthComputable – true or false, is the size of the request known?
    • loaded – number of bytes received so far
    • total – number of bytes expected for entire request

    The Contract

    When you’re looking at the properties of those progress events, certain rules apply that you can depend on. They are:

    • The total property will be 0 when lengthComputable is false.
    • The loadstart event is always signaled only once.
    • The progress event is fired off zero or more times after loadstart.

    And that’s it. Go forth and improve file uploads with Firefox 3.5 goodness.

  8. 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.

  9. 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:

  10. 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.