1. Introducing the new MDN website

    This week, Mozilla unveiled the newly redesigned Mozilla Developer Network, the latest incarnation of MDC. The website has evolved over the years and we recently decided to change the name from Mozilla Developer Center to the Mozilla Developer Network (MDN) to better reflect the developer segments that make up our community and provide a better platform for engaging developers in the Mozilla mission and our plans for pushing the open Web forward. In this blog post, we’ll walk you through some of the new features and content, in addition to some of the things you can expect in the months to come.

    Our Mission
    Upon first glance, the most obvious change is that the website has undergone a radical overhaul: from top to bottom, the entire MDN looks different. Even the tagline underneath the title is new: the Mozilla Developer Network is “a comprehensive, usable, and accurate resource for everyone developing for the Open Web.”

    The idea behind the tagline is perhaps the biggest change we’ve made to the MDN: we wanted to create a place where all web developers – not just people who develop using Mozilla technologies – can find the resources they need to make the Internet at-large a better place. This fundamental premise drove many of the design decisions incorporated into the new MDN.

    The New Home Page
    One of our main goals for this redesign was to streamline and simplify the process of finding information. Because the MDN home page is the first page most people will see when they visit the MDN, we wanted to make sure a diverse set of users could access as much information as possible without cluttering the page.

    Throughout the page, there are several opportunities for the user to sign up for an MDN account; if you already have an MDC/Deki account there’s no need to sign up again. If you’re new to MDN, you can easily register to join our community. Members will be able to log in to both the Developer Forums and the Docs Wiki.

    The page also features a promo box with revolving panes highlighting important open Web technologies and tools. The goal of the promo box is to direct developers to the pages about technologies that are most likely to be pertinent to their work, which helps reduce the number of steps it takes to reach a desired article. There are a lot of things happening at Mozilla that developers will care about, so this is where we hope to provide every visitor a chance to learn more about those topics.

    Moreover, the main content of the page will be available through a tabbed interface that will allow users to click through to whichever section in which they are interested. We currently have Docs and News but have plans to add Tools and Events as well. There are plans for the sidebar as well, but for now we have provided a live Twitter feed so that users can get a feel for what various Mozilla communities are talking about and sharing. We will eventually add trending topics based on activity from around the MDN, streams for conversations in the forums, and the latest web technology demos and experiments.

    Site Architecture
    The new MDN header contains a search bar and click-through access to various sections through the primary navigation. The MDN’s content has been separated into four main categories, each of which has its own navigation item: Web, Mobile, Add-ons, and Applications. This segmentation of the navigation allows us to organize content into non-overlapping buckets, which should more precisely direct developers to the content they need. Then we have the universal Docs – which takes users to a landing page leading to various articles and content from the Docs Wiki – and Community – which takes users to the Developer Forums for now – navigation items. Since those two areas are applicable to all developer segments, we kept them separate in the navigation layout.

    Each content page has a similar format: we feature a few popular articles for each category, some Mozilla-supplied tools, related news and updates, and a feed with relevant tweets. At the bottom of each page, there will eventually be popular forum topics and community comments. (Only the Add-ons page has this content right now). If you don’t find what you’re looking for on the landing page for any given category, there are links in each section of the page that take you to more options and pages. Despite the design overhaul, all of the information from the previous MDC remains intact, so there’s no need to worry about losing important articles. It’s all there and works exactly the same way as before.

    Also, any information that can be accessed via the Docs landing page can also be accessed from other pages on the MDN, but we wanted to provide an alternative way of presenting the information: we highlight some important web development topics, in addition to important topics from the other categories. There are also fun features like Doc of the Day and Most Active Docs, in case you’re interested in what everyone else is looking at.

    Growing the Community
    The final navigation item in the header is for Community and perhaps the most important addition to the new MDN: Developer Forums. In the previous version of the MDN, although there was plenty of documentation to be found, we didn’t provide developers much of an opportunity to talk, discuss, and ask questions. We felt that, in our goal to make the MDN a central hub for web developers, forums comprised an important feature to incorporate into the new version.

    Right now, there are five broad topics for discussion: Open Web, Mozilla Platform, MDN Community, Mozilla Add-ons, and Mozilla Labs. These domains should be able to cover much of the wide gamut of available discussion topics, but if not, we can always add new ones. Because the forums are new, they are still in the experimental stage; if you have any feedback for us, just use the feedback link at the bottom of the page. Feel free to start new threads and ask questions about anything, especially if it’s about documentation or the open web in general.

    We’d love for you to try out the new forums! Again, if you have an account for MDC/Deki, you can use that to log in; if not, you can use the link in the upper-right corner to become an MDN member.

    Submitting Feedback
    At the bottom of every page, there’s a link to submit feedback on the new MDN pages. Whether there’s something wrong or there’s something you’d like to see (or whether you’d just like to say hello!), just hit that link and let us know what’s on your mind. We’ll do what we can to integrate your ideas to make the Mozilla Developer Network a better place for all developers.

    Next Steps
    Though we have made quite a few changes to the Mozilla Developer Network, they certainly are not the last. As the MDN continues to expand, we have decided to create a next-generation Docs platform that the Mozilla web development team will be building on Django, similar to the one being implemented for the new SUMO site. Planning is already underway, and we hope to migrate documentation over sometime in 2011.

    Once we’ve converted all the content over, we plan to improve the way you find information via the search bar. So far, we have been devising ways to improve the tagging system and make sure that localized versions of articles are released as soon as possible. In addition, with the help of article rating and commenting systems, we can help make sure that the most relevant and accurate results are mentioned at the top of each search query. And finally, we are building a system that allows community experts in particular fields to regulate editing and writing of articles in their domains.

    We’re also looking to expand the Community tab. Though we expect the forums to remain the centerpiece of that section of the site, we hope to also bring you news, updates, and other community-sourced content.

    We hope that this has helped you get acquainted with the new Mozilla Developer Network. As always, we are amenable to your feedback and ideas, as we are as eager as you are to make the MDN an even better place for web developers to write, read, and discuss important Web topics. We look forward to hearing from you, and we hope you like the new MDN.

    Thanks!
    - Jay & Brian (+ the MDN team)

  2. Firefox 4: HTTP Strict Transport Security (force HTTPS)

    This article is about a new HTTPS header: Strict-Transport-Security, which force a website to be fetched through HTTPS. This feature will be part of Firefox 4.

    How do you type URLs?

    Do you prefix them with http:// or https:// systematically? Or do you just type example.com and let your browser add http://, like most of the people do?

    If a web page provide has an https version but you access it through http, what happens? The http version of the Website re-direct you to the https, but you first talked to the non-encrypted version of the website.

    These behaviors can be exploited to run a man-in-the-middle attack.

    To avoid this, you may want to force your website to be visited through https to transform any http://x.com request to https://x.com (with no client-server dialog).

    Sid Stamm recently integrated HTTP Strict Transport Security (HSTS) into
    Firefox. HSTS, specified in an IETF draft, allows sites to specify when they wish to be accessed only over https.

    A website can specify strict transport security for their domain via an HTTP header sent by the server set during an HTTPS response:

    Strict-Transport-Security: max-age=15768000

    or

    Strict-Transport-Security: max-age=15768000 ; includeSubDomains

    max-age sets how long to remember the forced HTTPS (seconds). If
    includeSubDomains is set, then this rule will apply to all the sub-domains too.

    In the future, any requests to x.com are modified to be via https if they are attempted through http before the request hits the network.

    This header is not considered during a non-encrypted HTTP transaction because the User-Agent doesn’t know if the https actually exists and also because the header can be injected by an attacker.

  3. Firefox 4: Drawing arbitrary elements as backgrounds with -moz-element


    This is a guest post by Markus Stange. Markus usually works on the Firefox Mac theme implementation, but this time he went on a small side trip through the Gecko layout engine in order to implement -moz-element.

    In Firefox Beta 4 we’re introducing a new extension to the CSS background-image property: the ability to draw arbitrary elements as backgrounds using -moz-element(#elementID).

    <p id="myBackground1" style="background: darkorange; color: white;  width: 300px; height: 40px;">
      This element will be used as a background.
    </p>
    <p style="background: -moz-element(#myBackground1); padding: 20px 10px; font-weight: bold;">
      This box uses #myBackground1 as its background!
    </p>



    A -moz-element() image works just like a normal url() image. That means it’s subject to all the familiar background properties like background-position, background-repeat, and even background-size.

    Using background-size you can create a thumbnail of the referenced element, for example:

    <ul id="thumbnails">
      <li style="background-image: -moz-element(#slide-0)"></li>
      <li style="background-image: -moz-element(#slide-1)"></li>
      <li style="background-image: -moz-element(#slide-2)"></li>
      <li style="background-image: -moz-element(#slide-3)"></li>
    </ul>
    #thumbnails li {
      width: 160px;
      height: 120px;
      background-repeat: no-repeat;
      background-size: contain;
    }



    There are three things to keep in mind about -moz-element:

    1. It’s live: whenever something happens in the referenced element, the -moz-element background image will be updated. It will also show things like text selection or blinking carets.

    2. It’s purely visual. That means you can’t “click through” to the original element. That’s by design.

    3. It works with any HTML element. Even with <iframe>



      <video>



      … and <canvas>.



    Canvas-as-background is in fact useful for some applications. For example, if you’re applying sepia tone to CSS background images in the browser, you now no longer have to convert the processed canvas image into a data URI. Instead, you can just set the canvas itself as the background image.

    Using a canvas as a background image is supported by Webkit, too, using -webkit-canvas().

    Painting loops

    A quick note on recursive references: If you try to paint an element that is already being painted via -moz-element, a painting loop will be detected and prevented. So you’ll need to think of a different way of drawing your Sierpinski carpets.

    Hiding the Referenced Element

    Sometimes you don’t want the original referenced element to be visible, only the -moz-element background image. So what do you do? You can’t just set display: none or visibility: hidden on the element, because then there’s nothing to draw in the -moz-element background image either – it will be transparent.

    Instead, you need to prevent the element from being rendered on the screen without really hiding it. One way of doing that is to wrap it with another element that has height: 0; overflow: hidden; set on it.

    There are three types of elements that are exempt from this rule: images, canvases and videos. These kinds of elements can have display: none and still be used in -moz-element. In fact, they don’t even need to be in the DOM.

    New DOM API:
    document.mozSetImageElement

    We added a new method to the document object: document.mozSetImageElement(<elementID>, <element>).

    Consider this piece of code:

    var slide5 = document.getElementById("slide-5");
    document.mozSetImageElement("current-slide", slide5);

    Now all elements with background-image: -moz-element(#current-slide) will draw the element with the ID slide-5, even if there is a real element with the ID current-slide!

    Calling document.mozSetImageElement("current-slide", null) will stop the override.

    This API can be handy in a variety of use cases. I already alluded to one of them in the previous section: with mozSetImageElement you can use canvas and image elements that aren’t part of the DOM tree.

    var img = new Image();
    img.src = "my_image.png";
    document.mozSetImageElement("image", img);
     
    var canvas = document.createElement("canvas");
    canvas.width = canvas.height = 100;
    var ctx = canvas.getContext("2d");
    // ... draw into ctx ...
    document.mozSetImageElement("canvas", canvas);

    View Demo

    Another scenario that benefits from mozSetImageElement involves JavaScript utility libraries. You might have a function like this:

    var runningNumber = 0;
    function addReflectionToElement(reflectedElement) {
      var referenceID = "reflected-element-" + runningNumber++;
      var reflection = document.createElement("div");
      reflection.className = "reflection";
      reflection.style.backgroundImage =
        "-moz-element(#" + referenceID + ")";
      document.mozSetImageElement(referenceID, reflectedElement);
      // ... insert reflection into the DOM ...
    }

    This way you can minimize the impact of your utility function because you don’t have to manipulate the ID of the element that was passed in.

    Finally, mozSetImageElement also allows you to reference elements from other documents, for example from inside iframes – obeying same origin restrictions, of course.

    -moz-element for SVG paint servers: patterns and gradients

    If you’ve ever written any SVG by hand you’re familiar with the concept of paint servers: those are the things you can use in your fill and stroke attributes when you don’t just want a single solid color. Now you can use them on HTML elements, too, using -moz-element:

    <p style="background: -moz-element(#pattern),
                          -moz-element(#gradient);
              padding: 10px; color: white">
      This element has both types of SVG paint servers
      in its background: a pattern and a gradient.
    </p>
     
    <svg height="0">
      <linearGradient id="gradient" x2="0" y2="1">
        <stop stop-color="black" offset="0%"/>
        <stop stop-color="red" offset="100%"/>
      </linearGradient>
      <pattern id="pattern" patternUnits="userSpaceOnUse"
               width="60" height="60">
        <circle fill="black" fill-opacity="0.5"
                cx="30" cy="30" r="10"/>
      </pattern>
    </svg>


    Note that we didn’t even have to use XHTML in order to be able to embed SVG thanks to our new HTML5 parser.

    This feature overlaps the functionality of CSS gradients and SVG images, but is very useful in some situations, such as animations. For example, say you want to create a progress bar with an animated gradient like this:

    You could do this with a CSS gradient and some JavaScript that periodically updates the background-position property. But you could also use an SVG gradient that’s animated with SMIL, requiring no JavaScript whatsoever:

    <div style="background: -moz-element(#animated-gradient);">
    </div>
     
    <svg height="0">
     
      <linearGradient id="animated-gradient" spreadMethod="reflect"
                      gradientUnits="userSpaceOnUse"
                      x1="16" x2="24" y2="0">
        <animate attributeName="x1" values="16; 0" dur="350ms"
                 repeatCount="indefinite"/>
        <animate attributeName="x2" values="24; 8" dur="350ms"
                 repeatCount="indefinite"/>
     
        <stop stop-color="#0F0" offset="0"/>
        <stop stop-color="#0D0" offset="100%"/>
      </linearGradient>
     
    </svg>

    View Demo

    The same could be achieved with CSS animations, but as long as they’re not implemented in Gecko you can use this.

    Support for SVG as a CSS background (bug 276431) will be added soon.

    Also, here’s a CSS + SVG Pacman for you.

    Applications

    I have two more suggestions for -moz-element usage:

    Reflections

    What is a reflection?

    #reflection {
      /* It's a copy of the original element... */
      background: -moz-element(#reflected-element)
                  bottom left no-repeat;
     
      /* ... turned upside down ... */
      -moz-transform: scaleY(-1);
     
      /* ... with a gradual fade-out effect towards the bottom. */
      mask: url(#reflection-mask);
    }



    Because we can apply arbitrary styles to the reflection, we can produce effects like animated water ripples.

    Fancy Slide Transitions

    In this demo I’d like to have a slideshow transition that looks like the upper half of the previous slide gets folded down to reveal the next slide:

    How would you implement this? You’ll obviously need to use some kind of transform, but on what element? The upper half of the slide needs to have a different transform than the lower half, so you can’t just set the transform on the slide itself.

    I ended up creating four new elements: #previousUpper, #previousLower, #nextUpper and #nextLower. I put them into a separate container called #transition which is only made visible while a transition is in progress. Then I gave them the right size and assigned the corresponding subimage of the previous / next slides to them using background-image: -moz-element(#previous/nextSlide) and the right background-position. And finally I set the transform on these helper elements.

    The code for it gets quite complex, though, so I’ll just direct you to the finished demo.

    More?

    My ideas for -moz-element demos have run out for the moment, but there’s bound to be more stuff one can do with it. Now it’s your turn!

    Credits

    Most of the credit here should go to Robert O’Callahan who cooked up the initial implementation back in 2008. After his initial experiments he had to work on more important things, though, so his patches lay dormant for about a year until he started a newsgroup thread to work out the right API in July 2009. Shortly after that, Ryo Kawaguchi revived roc’s work and spent the last weeks of his internship at Mozilla on it. Another year later I made the patch ready for review and drove it through the final stages until checkin.

    The same warnings as for mozRequestAnimationFrame apply: -moz-element and document.mozSetImageElement are experimental APIs. We do not guarantee to support them forever, and we wouldn’t evangelize sites to depend on them. We’ve implemented them so that people can experiment with them and we can collect feedback. We’ll propose it as a standard (minus the moz prefix, obviously), and author feedback on our implementation will help us make a better standard.

  4. Firefox 4 Beta: Latest Update is Here – what’s in for web developers?

    The latest Firefox 4 Beta has just been released (get it here). This beta comes with hundreds of bug fixes, Firefox Sync and Firefox Panorama. Here is a quick overview of the new features for web developers.

  5. HTML5 Video preload attribute supported in Firefox 4, autobuffer attribute removed

    This is a re-post from Chris Pearce’s blog. To comply with the HTML5 specification, we replaced the autobuffer attribute with the tri-state preload attribute. We encourage you to update your code. See the documention on MDC.

    Late last week I landed support on Firefox trunk for the HTML5 video ‘preload’ attribute. This replaces the ‘autobuffer’ attribute, which we previously supported. If you were previously using the autobuffer attribute on your HTLM5 videos, you need to update to using the preload attribute as well.

    The preload attribute provides a hint to the browser as to how much downloading is sensible for a given media. The preload attribute can have three values:

    1. none” – suggests to the browser that it doesn’t need to load this media at all until the user plays the resource. The browser will delay any network traffic required to load the media until the users tries to play the resource, or explicitly loads the resource. I suggest using this preload value, along with the poster attribute, when it’s unlikely that the user will play the resource. This is probably most useful in a mobile environment, where data can be expensive.
    2. metadata” – suggests to the browser that it isn’t necessary to load the entire resource in advance. The browser will suspend the load after loading metadata, displaying the first video frame (if there’s no poster image), and ensuring it can play the media. This is the default behaviour, and prevents excess network traffic when the web developer isn’t certain the video will definitely be played. If you don’t specify a preload value, Firefox will automatically do this. This was also the default behaviour in Firefox 3.5 and 3.6 in the absence of the autobuffer attribute. This default behaviour is a suitable compromise between bandwidth saving and user convenience.
    3. auto” – suggests to the browser that it should load as much of the resource as possible. As long as the browser’s own media cache isn’t full, it will keep on downloading. I suggest this is most useful in the “YouTube” case, when you’ve got a media which the user is almost certainly going to watch, and so having the user download the media is not likely to be wasting server bandwidth. This behaviour is the same as using the autobuffer attribute in Firefox 3.5 and 3.6

    Since the autobuffer attribute is no longer present in Firefox 4, and the preload attribute is not present in Firefox 3.5 and 3.6, if you want a media to download completely, you should include both preload=”auto” and autobuffer in the video element, e.g.:

    <video autobuffer preload=”auto” src=”video.ogg”></video>

    If you want the video to only be downloaded if the user actually plays the video, you should not include either the preload or the autobuffer attribute. The default behaviour in Firefox 3.5, 3.6, and the upcoming Firefox 4 is to only load up to the first frame and then suspend the download.

  6. HTML5 video ‘buffered’ property available in Firefox 4

    This is a repost from Chris Pearce’s blog.

    Recently I landed support for the HTML5 video ‘buffered’ property in Firefox. This is cool because we can now accurately determine which time-segments of a video we can play and seek into without needing to pause playback to download more data. Previously you could only get the byte position the download had reached, which often doesn’t map to the time ranges which are playable very well, especially in a variable bit rate video. This also can’t tell you if there are chunks which we skipped downloading before the downloaded byte position. Once the video controls UI is updated, users will be able to know exactly which segments of their video are downloaded and playable and can be seeked into without pausing playback to download more data.

    To see this in action, download a current Firefox nightly build , and point your browser at my video ‘buffered’ property demo. You’ll see something like the screenshot below, including an extra progress bar (implemented using canvas) showing the time ranges which are buffered.

    I’ve implemented the ‘buffered’ property for the Ogg and WAV backends. Support for the ‘buffered’ property for WebM is being worked on by Matthew Gregan, and is well underway. At the moment we return empty ranges for the ‘buffered’ property on video elements playing WebM and raw video.

    My checkin just missed the cutoff for Firefox 4 Beta 3, so the first beta release that the video ‘buffered’ property will appear in is Firefox 4 Beta 4.

  7. Help us to make Firefox 4 better: How to open a bug

    If you run Firefox Beta or Firefox nightlies, you will probably run into some issues. Reporting these bugs and crashes will help us to make sure the user experience is better for all Firefox 4 users.

    Marcia Knous is part of the Firefox QA team. Because reporting a good bug is not that easy but extremely important, Marcia explains us how to file a bug correctly:

    Starting out with bugzilla

    So you found a bug – To make sure this bug will be considered, you need to create an entry into our bug database: bugzilla. And as a good first step into Bugzilla, I strongly suggest you start by watching this video:

    Bugzilla For Humansby Johnathan Nightingale

    You can also use the Bugzilla Guided Tour which is a step by step Guide to filing a bug.

    Reporting a bug

    After you have a better grasp of how to file a bug, it’s time to gather the data we will need to enter the bug into Bugzilla.

    As we are web developers, experimenting with pre-release of Firefox and experimenting with new standards, you can be faced with crashes and incorrect behavior.

    Search Bugzilla for the bug first

    Although you may not find it, this will at least try to prevent duplicate bugs from being filed. Also consult the Bugs filed Today link to see if someone beat you to it!  You can also add ”’DUPEME”’ to the status whiteboard if you are unsure, and a query will pick that up so we can check to see if it a dupe.

    It’s a crash? Go get the Crash Information

    We are keeping a stack trace of crashes. You can see these traces
    if you type “about:crashes” in the URL bar

    Locate the crash stack – the latest one is the first of the list – it will look something like [@ libgcrypt.11.dylib@0xc21a ].

    Add it in that exact form in the Summary field. An example would be: Crash in [@ libgcrypt.11.dylib@0xc21a ] while loading Zimbra calendar.

    Paste the report ID link in the Bug Summary section.  (This is important so the crash shows up in crash-stats.mozilla.com with a bug associated to it). A report ID will look like this: bp-68a686c4-9a15-4326-a812-c8b772100812

    Have a Layout bug or Reproducible Crash? Add a Testcase

    As you can imagine, it’s way easier to work on a bug with a testcase.

    You can attach the testcase under the attachment section. And in this case, add the “testcase” keyword to the bug

    Make the Bug Summary useful

    Which version of Firefox do you run? To know that, we
    need the “Build ID”. Click “help” then “about Firefox/Minefield”.
    It should look like this:

    Mozilla/5.0 (X11; Linux i686; rv:2.0b4pre) Gecko/20100817 Minefield/4.0b4pre
    

    Also, include a set of Steps to Reproduce the bug. Please be as detailed as possible. For example, you should include whether you used the mouse or keyboard to initiate a command.  Mozilla Developer Bug Writing Guidelines has many other suggestions as to what you should include in the bug.

    These Bug Guidelines will take you through a tour of some of the other information that needs to be included, such as Product, Component, Version, Hardware/OS, and Keywords.

    (Tip: As a web developer, you probably want to open a bug into the Product “Core”. Then, choose the Component depending on the bug.)


    Thank you!!!

    We know how difficult it can be to open a bug. Opening a bug is extremely useful. So thank you so much to taking the time to make Firefox better!

  8. More efficient Javascript animations with mozRequestAnimationFrame

    This is a re-post from Robert O’Callahan’s blog.

    mozRequestAnimationFrame is an experimental API to make Javascript animations more efficient. We do not guarantee to support it forever, and I wouldn’t evangelize sites to depend on it. We’ve implemented it so that people can experiment with it and we can collect feedback. At the same time we’ll propose it as a standard (minus the moz prefix, obviously), and author feedback on our implementation will help us make a better standard.

    This feature will be available in Firefox 4 Beta 4.

    In Firefox 4 we’ve added support for two major standards for declarative animation — SVG Animation (aka SMIL) and CSS Transitions. However, I also feel strongly that the Web needs better support for JS-based animations. No matter how rich we make declarative animations, sometimes you’ll still need to write JS code to compute (“sample”) the state of each animation frame. Furthermore there’s a lot of JS animation code already on the Web, and it would be nice to improve its performance and smoothness without requiring authors to rewrite it into a declarative form.

    Obviously you can implement animations in JS today using setTimeout/setInterval to trigger animation samples and calling Date.now() to track animation progress. There are two big problems with that approach. The biggest problem is that there is no “right” timeout value to use. Ideally, the animation would be sampled exactly as often as the browser is able to repaint the screen, up to some maximum limit (e.g., the screen refresh rate). But the author has no idea what that frame rate is going to be, and of course it can even vary from moment to moment. Under some conditions (e.g. the animation is not visible), the animation should stop sampling altogether. A secondary problem is that when there are multiple animations running — some in JS, and some declarative animations — it’s hard to keep them synchronized. For example you’d like a script to be able to start a CSS transition and a JS animation with the same duration and have agreement on the exact moment in time when the animations are deemed to have started. At each paint you’d also like to have them sampled using the same “current time”.

    These problems have come up from time to time on mailing lists, for example on public-webapps. A while ago I worked out an API proposal and Boris Zbarsky just implemented it; it’s in Firefox 4 beta 4. Here’s the API, it’s really simple:

    • window.mozRequestAnimationFrame(): Signals that an animation is in progress, requests that the browser schedule a repaint of the window for the next animation frame, and requests that a MozBeforePaint event be fired before that repaint.
    • The browser fires a MozBeforePaint event at the window before we repaint it. The timeStamp attribute of the event is the time, in milliseconds since the epoch, deemed to be the “current time” for all animations for this repaint.
    • There is also a window.mozAnimationStartTime attribute, also in milliseconds since the epoch. When a script starts an animation, this attribute indicates when that animation should be deemed to have started. This is different from Date.now() because we ensure that between any two repaints of the window, the value of window.mozAnimationStartTime is constant, so all animations started during the same frame get the same start time. CSS transitions and SMIL animations triggered during that interval also use that start time. (In beta 4 there’s a bug that means we don’t quite achieve that, but we’ll fix it.)

    That’s it! Here’s an example; the relevant sample code:

    var start = window.mozAnimationStartTime;
    function step(event) {
      var progress = event.timeStamp - start;
      d.style.left = Math.min(progress/10, 200) + "px";
      if (progress < 2000) {
        window.mozRequestAnimationFrame();
      } else {
        window.removeEventListener("MozBeforePaint", step, false);
      }
    }
    window.addEventListener("MozBeforePaint", step, false);
    window.mozRequestAnimationFrame();

    It’s not very different from the usual setTimeout/Date.now() implementation. We use window.mozAnimationStartTime and event.timeStamp instead of calling Date.now(). We call window.mozRequestAnimationFrame() instead of setTimeout(). Converting existing code should usually be easy. You could even abstract over the differences with a wrapper that calls setTimeout/Date.now if mozAnimationStartTime/mozRequestAnimationFrame are not available. Of course, we want this to become a standard so eventually such wrappers will not be necessary!

    Using this API has a few advantages, even in this simple case. The author doesn’t have to guess a timeout value. If the browser is overloaded the animation will degrade gracefully instead of uselessly running the step script more times than necessary. If the page is in a hidden tab, we’ll be able to throttle the frame rate down to a very low value (e.g. one frame per second), saving CPU load. (This feature has not landed yet though.)

    One important feature of this API is that mozRequestAnimationFrame is “one-shot”. You have to call it again from your event handler if your animation is still running. An alternative would be to have a “beginAnimation”/”endAnimation” API, but that seems more complex and slightly more likely to leave animations running forever (wasting CPU time) in error situations.

    This API is compatible with browser implementations that offload some declarative animations to a dedicated “compositing thread” so they can be animated even while the main thread is blocked. (Safari does this, and we’re building something like it too.) If the main thread is blocked on a single event for a long time (e.g. if a MozBeforePaint handler takes a very long time to run) it’s obviously impossible for JS animations to stay in sync with animations offloaded to a compositing thread. But if the main thread stays responsive, so MozBeforePaint events can be dispatched and serviced between each compositing step performed by the compositing thread, I think we can keep JS animations in sync with the offloaded animations. We need to carefully choose the animation timestamps returned by mozAnimationStartTime and event.timeStamp and dispatch MozBeforePaint events “early enough”.

    EDIT: The mozRequestAnimationFrame Frame Rate Limit
    (from Robert O’Callahan’s blog)

    A few people have been playing with mozRequestAnimationFrame and noticed that they can’t get more than 50 frames per second. This is intentional, and it’s a good feature.

    On modern systems an application usually cannot get more than 50-60 frames per second onto the screen. There are multiple reasons for this. Some of them are hardware limitations: CRTs have a fixed refresh rate, and LCDs are also limited in the rate at which they can update the screen due to bandwidth limitations in the DVI connector and other reasons. Another big reason is that modern operating systems tend to use “compositing window managers” which redraw the entire desktop at a fixed rate. So even if an application updates its window 100 times a second, the user won’t be able to see more than about half of those updates. (Some applications on some platforms, typically games, can go full-screen, bypass the window manager and get updates onto the screen as fast as the hardware allows, but obviously desktop browsers aren’t usually going to do that.)

    So, firing a MozBeforePaint event more than about 50 times a second is going to achieve nothing other than wasting CPU (i.e., power). So we don’t. Apart from saving power, reducing animation CPU usage helps overall performance because we can use the free time to perform garbage collection or other house-cleaning tasks, reducing the incidence or length of frame skips.

    We need to do some followup work to make sure that on each platform we use the optimal rate; modern platforms have APIs to tell us the window manager’s composition rate. But 50Hz is almost always pretty close.

    This all means that measuring FPS is a bad way to measure performance, once you’re up to 50 or more. At that point you need to increase the difficulty of your workload.

    Tell us what you think.

  9. Firefox 4 Beta: Latest Update is Here – Experimenting With Multi-touch

    The latest Firefox 4 Beta has just been released (get it here). This beta comes with hundreds of bug fixes, improvements and multi-touch support for Windows 7 (see the release notes here). This article is about multi-touch support.

    Felipe Gomes is working on bringing multi-touch support to web content. In this latest beta, we are experimenting with this new feature.

    Playing with MultiTouch, HTML5 and CSS3:

    This video is hosted by YouTube and uses the HTML5 video tag if you have enabled it (see here). YouTube video here.

    Multi-touch Events

    If you have a multi-touch capable display, touch events are sent to your web page, more or less like mouse events. Each input (created using your fingers) generates its own events:

    • MozTouchDown: Sent when the user begins a screen touch action.
    • MozTouchMove: Sent when the user moves his finger on the touch screen.
    • MozTouchUp: Sent when the user lifts his finger off the screen.

    Touch information

    Touch events provide several useful properties.

    • event.streamId: don’t forget, it’s multi-touch, which means that you have to deal with several events from several sources. So each event comes with an id to identify the input.
    • event.mozInputSource: the type of device used (mouse, pen, or finger, if the hardware supports it). This is a property of mouse events.
    • event.clientX/Y: the coordinates.

    Designing a touch UI

    You might want to have a specific UI for multi-touch capable devices. You can use the :-moz-system-metric(touch-enabled) pseudo class or the -moz-touch-enabled media query to design a more finger friendly UI.

    Note: For now, this feature only works with Windows 7. If you don’t have hardware that supports multi-touch, you can try Hernan’s multi-touch simulator.

    More joy:

    (This video is made by Felipe, see more here).

    At the beginning of the video, you see how a webpage can get data about multi-touch input, correctly track points of contact and differentiate between touch input and pen input.

    At the second part, you see a visual application of multi-touch input on a fluid simulator, where each point of contact adds a particle source, and the movement adds forces to the field.

    Both parts use HTML5′s canvas element to render their content.

    Like it?

    Edit: If you want more details, take a look at Felipe’s latest blog post.

  10. Fun With Fast JavaScript

    This post is by Vladimir Vukićević and is a re-post from his personal weblog.

    Fast JavaScript is a cornerstone of the modern web. In the past, application authors had to wait for browser developers to implement any complex functionality in the browser itself, so that they could access it from script code. Today, many of those functions can move straight into JavaScript itself. This has many advantages for application authors: there’s no need to wait for a new version of a browser before you can develop or ship your app, you can tailor the functionality to exactly what you need, and you can improve it directly (make it faster, higher quality, more precise, etc.).

    Here are two examples that show off what can be done with the improved JS engine and capabilities that will be present in Firefox 4. The first example shows a simple web-based Darkroom that allows you to perform color correction on an image. The HTML+JS is around 700 lines of code, not counting jQuery. This is based on a demo that’s included with Google’s Native Client (NaCl) SDK; in that demo, the color correction work is done inside native code going through NaCl. That demo (originally presented as “too slow to run in JavaScript”) is a few thousand lines of code, and involves downloading and installing platform-specific compilers, multiple steps to test/deploy code, and installing a plugin on the browser side.

    I get about 15-16 frames per second with the default zoomed out image (around 5 million pixels per second — that number won’t be affected by image size) on my MacBook Pro, which is definitely fast enough for live manipulation. The algorithm could be tightened up to make this faster still. Further optimizations to the JS engine could help here as well; for example, I noticed that we spend a lot of time doing floating point to integer conversions for writing the computed pixels back to the display canvas, due to how the canvas API specifies image data handling.

    The Web Darkroom tool also supports drag & drop, so you can take any image from your computer and drop it onto the canvas to load it. A long (long!) time ago, back in 2006, I wrote an addon called “Croppr!”. It was intended to be used with Flickr, allowing users to play around with custom crops of any image, and then leave crop suggestions in comments to be viewed using Croppr. It almost certainly doesn’t work any more, but it would be neat to update it: this time with both cropping and color correction. Someone with the addon (perhaps a Jetpack now!) could then visit a Flickr photo and experiment, and leave suggestions for the photographer.

    The second example is based on some work that Dave Humphrey and others have been doing to bring audio manipulation to the web platform. Originally, their spec included a pre-computed FFT with each audio frame delivered to the web app. I suggested that there’s no need for this — while a FFT is useful for some applications, for others it would be wasted work. Those apps that want a FFT could implement one in JS. Some benchmark numbers backed this up — using the typed arrays originally created for WebGL, computing an FFT in JS was approaching the speed of native code. Again, both could be sped up (perhaps using SSE2 or something like Mono.Simd on the JS side), but it’s fast enough to be useful already.

    The demo shows this in action. A numeric benchmark isn’t really all that interesting, so instead I take a video clip, and as it’s playing, I extract a portion of the green channel of each frame and compute its 2D FFT, which is then displayed. The original clip plays at 24 frames per second, so that’s the upper bound of this demo. Using Float32 typed arrays, the computation and playback proceeds at around 22-24fps for me.

    You can grab the video controls and scrub to a specific frame. (The frame rate calculation is only correct while the video is playing normally, not while you’re scrubbing.) The video source uses Theora, so you’ll need a browser that can play Theora content. (I didn’t have a similar clip that uses WebM, or I could have used that.)

    These examples are demonstrating the strength of the trace-based JIT technique that Firefox has used for accelerating JavaScript since Firefox 3.5. However, not all code can see such dramatic speedups from that type of acceleration. Because of that, we’ll be including a full method-based JIT for Firefox 4 (for more details, see David Anderson’s blog, as well as David Mandelin’s blog). This will provide significantly faster baseline JS performance, with the trace JIT becoming a turbocharger for code that it would naturally apply to.

    Combining fast JavaScript performance alongside new web platform technologies such as WebGL and Audio will make for some pretty exciting web apps, and I’m looking forward to seeing what developers do with them!

    Edit: Made some last-minute changes to the demos, which ended up pulling in a slightly broken version of jQuery UI that wasn’t all that happy with Safari. Should be fixed now!