1. Firefox, YouTube and WebM

    Five important items of note today relating to Mozilla’s support for the VP8 codec:

    1. Google will be releasing VP8 under an open source and royalty-free basis. VP8 is a high-quality video codec that Google acquired when they purchased the company On2. The VP8 codec represents a vast improvement in quality-per-bit over Theora and is comparable in quality to H.264.

    2. The VP8 codec will be combined with the Vorbis audio codec and a subset of the Matroska container format to build a new standard for Open Video on the web called WebM. You can find out more about the project at its new site: http://www.webmproject.org/.

    3. We will include support for WebM in Firefox. You can get super-early WebM builds of Firefox 4 pre-alpha today. WebM will also be included in Google Chrome and Opera.

    4. Every video on YouTube will be transcoded into WebM. They have about 1.2 million videos available today and will be working through their back catalog over time. But they have committed to supporting everything.

    5. This is something that is supported by many partners, not just Google and others. Content providers like Brightcove have signed up to support WebM as part of a full HTML5 video solution. Hardware companies, encoding providers and other parts of the video stack are all part of the list of companies backing WebM. Even Adobe will be supporting WebM in Flash. Firefox, with its market share and principled leadership and YouTube, with its video reach are the most important partners in this solution, but we are only a small part of the larger ecosystem of video.

    We’re extremely excited to see Google joining us to support Open Video. They are making technology available on terms consistent with the Open Web and the W3C Royalty-Free licensing terms. And – most importantly – they are committing to support a full open video stack on the world’s largest video site. This changes the landscape for video and moves the baseline for what other sites have to do to maintain parity and keep up with upcoming advances in video technology, not to mention compatibility with the set of browsers that are growing their userbase and advancing technology on the web.

    At Mozilla, we’ve wanted video on the web to move as fast as the rest of the web. That has required a baseline of open technology to build on. Theora was a good start, but VP8 is better. Expect us to start pushing on video innovation with vigor. We’ll innovate like the web has, moving from the edges in, with dozens of small revolutions that add up to something larger than the sum of those parts. VP8 is one of those pieces, HTML5 is another. If you watch this weblog, you can start to see those other pieces starting to emerge as well. The web is creeping into more and more technologies, with Firefox leading the way. We intend to keep leading the web beyond HTML5 to the next place it needs to be.

    Today is a day of great change. Tomorrow will be another.

  2. Firefox 4: the HTML5 parser – inline SVG, speed and more

    This is a guest post from Henri Sivonen, who has been working on Firefox’s new HTML5 parser. The HTML parser is one of the most complicated and sensitive pieces of a browser. It controls how your HTML source is turned into web pages and as such changes to it are rare and need to be well-tested. While most of Gecko has been rebuilt since its initial inception in the late 90s, the parser was one of the stand-outs as being “original.” This replaces that code with a new parser that’s faster, compliant with the new HTML5 standard and enables a lot of new functionality as well.

    A project to replace Gecko’s old HTML parser, dating from 1998, has been ongoing for some time now. The parser was just turned on by default on the trunk, so you can now try it out by simply downloading a nightly build without having to flip any configuration switch.

    There are four main things that improve with the new HTML5 parser:

    • You can now use SVG and MathML inline in HTML5 pages, without XML namespaces.
    • Parsing is now done off Firefox’s main UI thread, improving overall browser responsiveness.
    • It’s improved the speed of innerHTML calls by about 20%.
    • With the landing of the new parser we’ve fixed dozens of long-standing parser related bugs.

    Try the demo with a Firefox Nightly or another HTML5-ready browser. It should look like this:

    What Is It?

    The HTML5 parser in Gecko turns a stream of bytes into a DOM tree according to the HTML5 parsing algorithm.

    HTML5 is the first specification that tells implementors, in detail, how parse HTML. Before HTML5, HTML specifications didn’t say how to turn a stream of bytes into a DOM tree. In theory, HTML before HTML5 was supposed to be defined in terms of SGML. This implied a certain relationship between the source of valid HTML documents and the DOM. However, parsing wasn’t well-defined for invalid documents (and Web content most often isn’t valid HTML4) and there are SGML constructs that were in theory part of HTML but that in reality popular browsers didn’t implement.

    The lack of a proper specification led to browser developers filling in the blanks on their own and reverse engineering the browser with the largest market share (first Mosaic, then Netscape, then IE) when in doubt about how to get compatible behavior. This led to a lot of unwritten common rules but also to different behavior across browsers.

    The HTML5 parsing algorithm standardizes well-defined behavior that browsers and other applications that consume HTML can converge on. By design, the HTML5 parsing algorithm is suitable for processing existing HTML content, so applications don’t need to continue maintaining their legacy parsers for legacy content. Concretely, in the trunk nightlies, the HTML5 parser is used for all text/html content.

    How Is It Different?

    The HTML5 parsing algorithm has two major parts: tokenization and tree building. Tokenization is the process of splitting the source stream into tags, text, comments and attributes inside tags. The tree building phase takes the tags and the interleaving text and comments and builds the DOM tree. The tokenization part of the HTML5 parsing algorithm is closer to what Internet Explorer does than what Gecko used to do. Internet Explorer has had the majority market share for a while, so sites have generally been tested not to break when subjected to IE’s tokenizer. The tree building part is close to what WebKit does already. Of the major browser engines WebKit had the most reasonable tree building solution prior to HTML5.

    Furthermore, the new HTML5 parser parses network streams off the main thread. Traditionally, browsers have performed most tasks on the main thread. Radical changes like off-the-main-thread parsing are made possible by the more maintainable code base of the HTML5 parser compared to Gecko’s old HTML parser.

    What’s In It for Web Developers?

    The changes mentioned above are mainly of interest to browser developers. A key feature of the HTML5 parser is that you don’t notice that anything has changed.

    However, there is one big new Web developer-facing feature, too: inline MathML and SVG. HTML5 parsing liberates MathML and SVG from XML and makes them available in the main file format of the Web.

    This means that you can include typographically sophisticated math in your HTML document without having to recast the entire document as XHTML or, more importantly, without having to retrofit the software that powers your site to output well-formed XHTML. For example, you can now include the solution for quadratic equations inline in HTML:

    <math>
      <mi>x</mi>
     
      <mo>=</mo>
      <mfrac>
        <mrow>
          <mo>&minus;</mo>
          <mi>b</mi>
          <mo>&PlusMinus;</mo>
          <msqrt>
            <msup>
     
              <mi>b</mi>
              <mn>2</mn>
            </msup>
            <mo>&minus;</mo>
            <mn>4</mn>
            <mo>&InvisibleTimes;</mo>
            <mi>a</mi>
     
            <mo>&InvisibleTimes;</mo>
            <mi>c</mi>
          </msqrt>
        </mrow>
        <mrow>
          <mn>2</mn>
          <mo>&InvisibleTimes;</mo>
          <mi>a</mi>
     
        </mrow>
      </mfrac>
    </math>

    Likewise, you can include scalable inline art as SVG without having to recast your HTML as XHTML. As screen sized and pixel densities become more varied, making graphics look crisp at all zoom levels becomes more important. Although it has previously been possible to use SVG graphics in HTML documents by reference (using the object element), putting SVG inline is more convenient in some cases. For example, an icon such as a warning sign can now be included inline instead of including it from an external file.

    <svg height=86 width=90 viewBox='5 9 90 86' style='float: right;'>
      <path stroke=#F53F0C stroke-width=10 fill=#F5C60C stroke-linejoin=round d='M 10,90 L 90,90 L 50,14 Z'/>
      <line stroke=black stroke-width=10 stroke-linecap=round x1=50 x2=50 y1=45 y2=75 />
    </svg>

    Make yourself a page that starts with <!DOCTYPE html> and put these two pieces of code in it and it should work with a new nightly.

    In general, if you have a piece of MathML or SVG as XML, you can just copy and paste the XML markup inline into HTML (omitting the XML declaration and the doctype if any). There are two caveats: The markup must not use namespace prefixes for elements (i.e. no svg:svg or math:math) and the namespace prefix for the XLink namespace has to be xlink.

    In the MathML and SVG snippits above you’ll see that the inline MathML and SVG pieces above are more HTML-like and less crufty than merely XML pasted inline. There are no namespace declarations and unnecessary quotes around attribute values have been omitted. The quote omission works, because the tags are tokenized by the HTML5 tokenizer—not by an XML tokenizer. The namespace declaration omission works, because the HTML5 tree builder doesn’t use attributes looking like namespace declarations to assign MathMLness or SVGness to elements. Instead, <svg> establishes a scope of elements that get assigned to the SVG namespace in the DOM and <math> establishes a scope of elements that get assigned to the MathML namespace in the DOM. You’ll also notice that the MathML example uses named character references that previously haven’t been supported in HTML.

    Here’s a quick summary of inline MathML and SVG parsing for Web authors:

    • <svg></svg> is assigned to the SVG namespace in the DOM.
    • <math></math> is assigned to the MathML namespace in the DOM.
    • foreignObject and annotation-xml (an various less important elements) establish a nested HTML scope, so you can nest SVG, MathML and HTML as you’d expect to be able to nest them.
    • The parser case-corrects markup so <SVG VIEWBOX=’0 0 10 10′> works in HTML source.
    • The DOM methods and CSS selectors behave case-sensitively, so you need to write your DOM calls and CSS selectors using the canonical case, which is camelCase for various parts of SVG such as viewBox.
    • The syntax <foo/> opens and immediately closes the foo element if it is a MathML or SVG element (i.e. not an HTML element).
    • Attributes are tokenized the same way they are tokenized in HTML, so you can omit quotes in the same situations where you can omit quotes in HTML (i.e. when the attribute value is not the empty string and does not contain whitespace, ", , `, <, =, or >).
    • Warning: the two above features do not combine well due to the reuse of legacy-compatible HTML tokenization. If you omit quotes on the last attribute value, you must have a space before the closing slash. <circle fill=green /> is OK but <circle fill=red/> is not.
    • Attributes starting with xmlns have absolutely no effect on what namespace elements or attributes end up in, so you don’t need to use attributes starting with xmlns.
    • Attributes in the XLink namespace must use the prefix xlink (e.g. xlink:href).
    • Element names must not have prefixes or colons in them.
    • The content of SVG script elements is tokenized like they are tokenized in XML—not like the content of HTML script elements is tokenized.
    • When an SVG or MathML element is open <![CDATA[]]> sections work the way they do in XML. You can use this to hide text content from older browsers that don’t support SVG or MathML in text/html.
    • The MathML named characters are available for use in named character references everywhere in the document (also in HTML content).
    • To deal with legacy pages where authors have pasted partial SVG fragments into HTML (who knows why) or used a <math> tag for non-MathML purposes, attempts to nest various common HTML elements as children of SVG elements (without foreignObject) will immediately break out of SVG or MathML context. This may make some typos have surprising effects.
  3. Firefox 4: Better performance with Lazy Frame Construction

    This is a re-post from Timothy Nikkel’s blog.

    Lazy Frame Construction is new to Gecko and allows many DOM operations (appendChild, insertBefore, etc) to not trigger immediate reflows. This can vastly improve the interactive performance of very complex web pages. If you want to test this out, you should get a Firefox Nightly.

    Lazy frame construction recently landed on mozilla-central. To explain what this means and how this improves things we need some background. Each node in the DOM tree of a webpage has a frame created for it that is used to determine where on the page the node is drawn and its size. A frame corresponds closely to the concept of a box from the CSS spec. We used to create frames for DOM nodes eagerly; that is as soon as a node was inserted into the document we would create a frame for it. But this can create wasted effort in many situations. For example if a script inserts a large number of nodes into the DOM we would create a frame for each node when it is inserted. But with lazy frame construction we can process all those nodes at once in a big batch, saving overhead. Furthermore the time it takes to create those frames no longer blocks that script, so the script can go and do what it needs to and the frames will get created when they are needed. There are other situations where a script would insert nodes into the document and remove them immediately, so there is no need to ever create a frame for these as they would never be painted on screen.

    So now when a node is inserted into a document the node is flagged for needing a frame created for it, and then the next time the refresh driver notifies (currently at 20 ms intervals) the frame is created. The refresh driver is also what drives reflow of webpages and CSS & SVG animations.

    Let’s look at two examples where lazy frame construction helps.

    In this example we insert 80000 div elements and then we flush all pending layout to time how long it takes before the changes made by the script are done and visible to the user. The script can continue executing without flushing layout, but we do it here to measure how long the actual work takes.

    var stime = new Date();
    var container = document.getElementById("container");
    var lastchild = document.getElementById("lastchild");
    for (var i = 0; i < 80000; i++) {
      var div = document.createElement("div");
      container.insertBefore(div, lastchild);
    }
    document.documentElement.offsetLeft; // flush layout
    var now = new Date();
    var millisecondselapsed = (now.getTime() - stime.getTime());

    With lazy frame construction we are able to process the insertion of all 80000 div elements in one operation, saving the overhead of 80000 different inserts. In a build without lazy frame construction I get an average time of 1358 ms, with lazy frame construction I get 777 ms.

    This example comes from a real webpage. We append a div and then set “div.style.position = ‘absolute’;”, and repeat that 2000 times, and then we flush all pending layout to time how long it takes before the changes made by the script are done and visible to the user.

    var stime = new Date();
    var container = document.getElementById("container2");
    for (var i = 0; i < 2000; i++) {
      var div = document.createElement("div");
      container.appendChild(div);
      div.style.position = "absolute";
    }
    document.documentElement.offsetLeft; // flush layout
    var now = new Date();
    var millisecondselapsed = (now.getTime() - stime.getTime());

    With lazy frame construction we don't even bother creating the frame for the div until after the position has been set to absolute, so we don't waste any effort. In a build without lazy frame construction I get an average time of 4730 ms, with lazy frame construction I get 130 ms.

  4. Firefox 4: -moz-any() selector grouping

    This is a re-post from David Baron’s blog. This feature has landed in Mozilla Central (trunk) and only available with a Firefox Nightly Build for the time being.

    Last night I landed support for :-moz-any() selector grouping. This allows providing alternatives between combinators, rather than having to repeat the entire selector for once piece that’s different. For example, it allowed replacing this rule in our user-agent style sheet:

    /* 3 deep (or more) unordered lists use a square */
    ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
    ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
    ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
    ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
    ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
    ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
    menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
    menu ol menu, menu ul menu, menu menu menu, menu dir menu,
    menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
    dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
    dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
    dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
      list-style-type: square;
    }

    with this one:

    /* 3 deep (or more) unordered lists use a square */
    :-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul,
    :-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) menu,
    :-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) dir {
      list-style-type: square;
    }

    In theory, I could even have used:

    /* 3 deep (or more) unordered lists use a square */
    :-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
      list-style-type: square;
    }

    but this would have been slower since it no longer falls into the tag bucket. (If :-moz-any() turns out to be popular, we could add extra code so it’s just as fast, but I haven’t done so yet.)

    :-moz-any() is allowed to contain selectors with multiple simple selectors (using the css3-selectors definition of simple selectors, not the CSS 2.1 definition), but it is not allowed to contain combinators or pseudo-elements. So you can write :-moz-any(p.warning.new, p.error, div#topnotice) or :-moz-any(:link, :visited).external:-moz-any(:active, :focus), but you can’t put “div p” or “div > p or “:first-letter” inside :-moz-any().

    This has a -moz- prefix for two reasons. First, it’s just a proposal, and hasn’t made its way into any specification. And second, it isn’t quite ready for prime-time, though, since it doesn’t yet handle specificity correctly.

    Note: This will be extremely valuable in an HTML5 context when it comes to sections and headings. Since section, article, aside, and nav can be nested, doing something like styling all h1 elements at different depths could be extremely complex.

    /* Level 0 */
    h1 {
      font-size: 30px;
    }
    /* Level 1 */
    section h1, article h1, aside h1, nav h1 {
      font-size: 25px;
    }
    /* Level 2 */
    section section h1, section article h1, section aside h1, section nav h1,
    article section h1, article article h1, article aside h1, article nav h1,
    aside section h1, aside article h1, aside aside h1, aside nav h1,
    nav section h1, nav article h1, nav aside h1, nav nav h1, {
      font-size: 20px;
    }
    /* Level 3 */
    /* ... don't even think about it*/

    With -moz-any():

    /* Level 0 */
    h1 {
      font-size: 30px;
    }
    /* Level 1 */
    -moz-any(section, article, aside, nav) h1 {
      font-size: 25px;
    }
    /* Level 2 */
    -moz-any(section, article, aside, nav)
    -moz-any(section, article, aside, nav) h1 {
      font-size: 20px;
    }
    /* Level 3 */
    -moz-any(section, article, aside, nav)
    -moz-any(section, article, aside, nav)
    -moz-any(section, article, aside, nav) h1 {
      font-size: 15px;
    }
  5. Revitalizing Caching

    Apparently, there are only two hard problems in computer science: cache invalidation and the naming of things (or so Phil Karlton’s dictum goes). Earlier this month, we invited representatives of Twitter, Facebook, SproutCore, Palm’s webOS, Microsoft’s “Office On The Web”, Yahoo, and Google to talk to us about the former problem (amongst other things), though we also learned something about the latter.

    Caching is an important issue to get right on the web, not least of all because of the proliferation of web applications on mobile devices. The goals of our caching summit were to identify use cases that would help us move forward with caching and with HTTP request efficiency. How desirable was rolling up our sleeves to look at HTTP/1.1 Pipelining in Firefox, for instance? What else was needed at the HTTP layer? And was the vaunted HTML5 AppCache, implemented in Firefox 3.5 onwards, actually useful to developers? What else needed to be exposed to web applications, either within content or via additional headers?

    Developer feedback is invaluable, and is increasingly the basis of how we want to evolve the next integral pieces of the web platform. Web developers are one of our primary constituencies; going forward, we want them to help us prioritize what we should implement, and what we need to focus on with respect to web standards. We chose our attendees wisely; if any group of people could talk about web applications at scale, the current performance of the cache, and their wishlist for future browser caching behavior on the web platform, it was this group of people. And the feedback they gave us was copious and useful — our work is cut-out for us. Notably, we’ve got a few actions we’re going to follow-up on:

    • Increase the default size of our disk and memory caches. Firefox’s disk cache is currently set at 50MB, a small-ish number given the amount of disk space available on hardware currently (and although this limit can be increased using advanced preferences, few users actually change the default). This is low-hanging fruit for us to fix. An interesting open question is whether we should determine disk cache size heuristically, in lieu of choosing a new upper bound. Steve Souders, who attended our caching summit, blogs about cache sizes, as well as premature cache evictions.

    • Conduct a “Mozilla Test-Pilot” project to get more data about how exactly we cache resources currently. This is part of a larger question about updating our caching algorithm. Like other browsers, we use an optimization of the Least Recently Used (LRU) caching algorithm, called LRU-SP. Data that we would want to gather includes determining what the hit rate, mean, variance and distribution of cached resources are. What’s the average lifetime? How about different modes where our LRU-SP replacement policy doesn’t work well for certain apps, where big resources (such as an essential script file) may get eliminated before smaller ones (such as map tiles)? We’ll also have to research the role that anti-virus software plays in routinely flushing out the cache, leading to further occurrences of untimely eviction of relevant resources.

    • Explore prioritization of resources in the cache based on MIME type. For instance, allowing for JavaScript (text/javascript) to always get higher priority in terms of what gets pruned by our LRU-SP algorithm. A good follow-up for this would be to get Chrome, IE, Apple, and Opera to discuss this with us, and then document what we come up with as a MIME-type based “naive” prioritization. We also want to allow developers to set resource priority on their own, perhaps through a header. This is likely to be an ongoing discussion.

    • Really figure out what hampers the adoption of HTTP/1.1 Pipelining on the web, including data from proxies and how they purge. While Pipelining is enabled in Mobile Firefox builds (such at that running on the Nokia N900 and on Android devices) by default, we have it turned off in desktop Firefox builds. We do this for a variety of reasons, not least of all the risk of performance slow downs if one of the pipelined requests slows down the others. It’s clear from our discussion that many who attended our caching summit think pipelining will help their applications perform much better. The situation on the web now with respect to pipelining is a kind of hostage’s dilemma: of the main desktop browsers, nobody has turned on pipelining, for fear of a scenario that slows down performance (leading to that particular browser being accused of “being slow”). The developers who visited us threw down the proverbial gauntlet; at a minimum we’ve got to figure out what hamstrings the use of pipelining on the web, and determine what we can actually do to remove those obstacles.

    • Figure out how to evolve the HTML5 AppCache, which frankly hasn’t seen the adoption we initially expected. While we tend to view parts of HTML5 such as Cache Manifests and window.applicationCache as yet another performance tool (to ensure web applications rapidly load upon subsequent accesses), it is different than the general browser cache. What’s in a name, and why is naming something amongst the hardest problems in computer science? The use of the word “cache” to describe the parts of HTML5 that deal with offline web applications has confused some developers. What we’re calling the HTML5 AppCache was primarily conceived of to enable offline web application use, but many applications (such as those built with SproutCore) treat it as an auxiliary cache, to ensure that applications have a rapid start-up time and generally perform well. Why, we were asked, should we have two things: a general purpose browser cache, and something else, uniquely for offline usage? On the one hand, the HTML5 AppCache allows web apps to act like native apps (enabling “rapid-launch icons” on some mobile handsets), perhaps even eventually integrating with native application launchers. And on the other hand, the HTML5 AppCache’s separateness from the general cache may mean that we coin different APIs to work with the general cache. In general, simultaneously evolving multiple APIs with “cache” in the name may be confusing. But that’s why naming is amongst the hard problems, and that’s why we have to architect the next iteration mindful of the potential for both redundancy as well as confusion.

    • We’ve got a tracking bug in place with a bold moniker: “Improve HTTP Cache.” You’ll see the gamut of changes we’d like to introduce here, including benchmarking our cache against Chromium’s (and perhaps just using Chromium’s cache code, if we need to).

      Caching is important, but difficult. It would be fair to describe most of the near-term evolution of the web that way, whether that is the introduction of an indexable database capability, streaming video, or new layout models within CSS. These evolutions won’t necessarily happen within a standards body or on a listserv, but rather through rapid prototyping and meaningful feedback. That’s why we have to talk to web developers to help us do the right thing, and that’s why we’ll keep organizing meet-ups such as the recent caching summit.

  6. Firefox 4: easier JS form handling with FormData

    This feature has landed in Mozilla Central (trunk) and only available with a Firefox Nightly Build for the time being.

    XMLHttpRequest Level 2 (editor’s draft) adds support for the new FormData interface. FormData objects provide a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest send() method in “multipart/form-data” format.

    Why FormData?

    When you want to send complex data to a server from a web page (files, non-ASCII content), you must use the multipart/form-data content type. To set the content type in a <form>, you write:

    <form method="post" enctype="multipart/form-data" action="http://foo.bar/upload.php">
    <input type="file" name="media"/>
    <input name="nickname"/>
    <input name="website"/>
    <input type="submit" value="upload"/>
    </form>

    This is what you usually do to upload a file.

    Starting with Firefox 3.6, you can manipulate files with JavaScript (see File API), and maybe you want to send files using XMLHttpRequest. But if, for example, you want to reproduce this form, it’s really hard because you’ll have to create the multipart/form-data content yourself in JavaScript (see, for example, this code I wrote a while ago implementing a multipart/form-data: ugly and slow).

    This is where FormData is useful: to reproduce the <form> submission mechanism in JavaScript

    The FormData object

    The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest. This object has only one method:

    append(key, value);

    where key is the name of your value, and where value can be a string or a file.

    You can create a FormData object, append values and then send it through XMLHttpRequest. If you want to simulate the previous form, you write:

    // aFile could be from an input type="file" or from a Dragged'n Dropped file
    var formdata = new FormData();
    formdata.append("nickname", "Foooobar"); 
    formdata.append("website", "http://hacks.mozilla.org");
    formdata.append("media", aFile);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://foo.bar/upload.php");  
    xhr.send(formdata);

    FormData and the <form> element

    Firefox extends the HTML form element slightly, adding a getFormData() method that lets you fetch a form’s data as a FormData object. This is not yet part of the HTML standard, but is expected to be added to the specification at some point in the future (although possibly with a different name):

    var formElement = document.getElementById("myFormElement");
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "submitform.php");
    xhr.send(formElement.getFormData());

    You can also add data to the FormData object between retrieving it from a form and sending it, like this:

    var formElement = document.getElementById("myFormElement");
    formData = formElement.getFormData();
    formData.append("serialnumber", serialNumber++);
    xhr.send(formData);

    This lets you augment the form’s data before sending it along, to include additional information that’s not necessarily user editable on the form.

    Resources

  7. Fast JavaScript and Audio: Speech Synthesis in Your Browser

    If you haven’t been keeping track of David Humphrey’s work to bring audio manipulation to Firefox, you’re missing out. He’s made an update post with a huge number of demos, requiring some of the most recent advances in JavaScript found in Firefox – binary arrays, super-fast tracing-based FFT analysis, etc. This was my favorite bit of his post:

    I think that my favourite demo by far this time around is one that I’ve been waiting to see since we first began these experiments. I’ve written in the past that our work could be used to solve many web accessibility problems. A few weeks ago I mentioned on irc that someone should take a shot at building a text to speech engine in JavaScript, now that we have typed arrays. Yury quietly went off and built one based on the flite engine. When you run this, remember that you’re watching a browser speak with no plugins of any kind. This is all done in JavaScript.

    Web Audio Data API – Text to Speech Demo from David Humphrey on Vimeo.

  8. Getting involved with Account Manager

    It’s been a couple of weeks since we originally posted about Account Manager and we’ve gotten a lot of feedback. We’ve got a few opportunities for people to get more involved with the project, listed below.

    Join us at the Account Manager Meet-up or at IIW

    We are hosting an Account Manager Meet-up on Friday, May 21st at Mozilla’s Mountain View Headquarters. This meetup will be an excellent opportunity to give your feedback on the draft specification as we prepare to finalize it. So, if you are a web developer, sysadmin, protocol or security expert, RSVP here.

    The summit will be from 1PM to 4PM followed by a “cantina” during which you’ll get a chance to meet with other Mozilla developers over informal drinks and snacks.

    We’ll also be presenting at the Internet Identity Workshop next week; if you are planning on attending IIW look for the Account Manager talk and come and say hello!

    Browser-assisted registration

    Another way to help out is to add reigistration support to your site. The latest version of the Account Manager add-on adds support for a basic registration flow, and we’re very interested in finding out what the Web development community thinks about it. Here’s what you need to do:

    Add a snippet to the username-password-form profile in your AMCD:

    "register": {
        "method": "POST",
        "path": "/register-endpoint",
        "id-type": "email"
    }

    Then you need to add a method at /register-endpoint which will receive the user id and secret as POST parameters. Your method should return 200 if the id and secret are OK, otherwise return 400 with a snippet of JSON (see the spec for details and examples).

    You might need to change your content to accomodate this new model: after you return 200 the expectation is that there is a username+password pair which is valid, even though it might map to a disabled account. For example, if you need to ask for additional information, have the user solve a captcha, or require email verification, simply keep the account disabled until those additional requirements have been met.

    Addressing cross-site request forgeries

    Based on feedback from the community, we’ve been investigating several possibilities for preventing CSRF attacks with Account Manager. In addition to supporting CSRF tokens, the latest proposal leverages headers to achieve the same goal with fewer requests and without a session cookie. Interested? Join the discussion on our forum.

    Join us online

    Join our online community, visit the Account Manager feature page to learn more about Account Manager, and to subscribe to our mailing list/forum.

    If you add support for Account Manager to your site, please add yourself to the the wiki page for early Account Manager sites.

  9. upcoming changes to the viewport meta tag for firefox mobile

    This is a guest post by Matt Brubeck who works on the Firefox Mobile team.

    The upcoming release of Mobile Firefox (Fennec) 1.1 features improved
    support for the <meta name="viewport"> tag. Previous version of Fennec supported the width, height, and initial-scale viewport properties, but had problems with some sites designed for iPhone and Android browsers. We now support the same properties Mobile Safari does, and we also changed Fennec to render mobile sites more consistently on screens of different sizes and resolutions.

    touch.facebook.com before:

    touch.facebook.com after:

    You can see these changes for yourself in the latest Fennec 1.1 and trunk nightly builds for Maemo, Android, Windows, Mac, or Linux.

    Background

    Mobile browers like Fennec render pages in a virtual “window” (the viewport), usually wider than the screen, so they don’t need to squeeze every page layout into a tiny window (which would break many non-mobile-optimized sites). Users can pan and zoom to see different areas of the page.

    Mobile Safari introduced the “viewport meta tag” to let web developers control the viewport’s size and scale. Many other mobile browsers now support this tag, although it is not part of any web standard. Apple’s documentation does a good job explaining how web developers can use this tag, but we had to do some detective work to figure out exactly how to implement it in Fennec. For example, Safari’s documentation says the content is a “comma-delimited list,” but existing browsers and web pages use any mix of commas, semicolons, and spaces as separators.

    Viewport basics

    A typical mobile-optimized site contains something like the following:

    <meta name="viewport"
     content="width=device-width, initial-scale=1, maximum-scale=1"/>

    The width property controls the size of the viewport. It can be set to a specific number of pixels like width=600 or to the special value device-width value which is the width of the screen in CSS pixels at a scale of 100%. (There are corresponding height and device-height values, which may be useful for pages with elements that change size or position based on the viewport height.)

    The initial-scale property controls the zoom level when the page is first loaded. The maximum-scale, minimum-scale, and user-scalable properties control how users are allowed to zoom the page in or out.

    A pixel is not a pixel

    The iPhone and many popular Android phones have 3- to 4-inch (7–10 cm) screens with 320×480 pixels (~160 dpi). Firefox for Maemo runs on the Nokia N900, which has the same physical size but 480×800 pixels (~240 dpi). Because of this, the last version of Fennec displayed many pages about one third smaller (in actual, physical size) than iPhone or Android. This caused usability and readability problems on many touch-optimized web sites. Peter-Paul Koch wrote about this problem in A pixel is not a pixel.

    Fennec 1.1 for Maemo will use 1.5 hardware pixels for each CSS “pixel”, following the lead of Android’s WebKit-based browser. This means a page with initial-scale=1 will render at close to the same physical size in Fennec for Maemo, Mobile Safari for iPhone, and the Android Browser on both HDPI and MDPI phones. This is consistent with the CSS 2.1 specification, which says:

    If the pixel density of the output device is very different from that of a typical computer display, the user agent should rescale pixel values. It is recommended that the pixel unit refer to the whole number of device pixels that best approximates the reference pixel. It is recommended that the reference pixel be the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length.

    For web developers, this means that 320px be full width in portrait mode at scale=1, on all of the above-mentioned handheld devices, and they may size their layouts and images accordingly. But remember that not all mobile devices are the same width; you should also make sure that your pages work well in landscape mode, and on larger devices like the iPad and Android tablets.

    On 240-dpi screens, pages with initial-scale=1 will effectively be zoomed to 150% by both Fennec and Android WebKit. Their text will be smooth and crisp, but their bitmap images will probably not take advantage of the full screen resolution. To get sharper images on these screens, web developers may want to design images – or whole layouts – at 150% of their final size (or 200%, to support the rumored 320-dpi iPhone) and then scale them down using CSS or viewport properties.

    Right now Fennec uses the same default ratio of 1.5 on all devices. (It’s a hidden preference that can be changed in about:config or by an add-on.) Later we’ll need to change this – as well as many other parts of Fennec’s user interface – to work correctly on screens with different pixel densities. Note that the default ratio of 1.5 is true only when the viewport scale equals 1. Otherwise, the relationship between CSS pixels and device pixels depends on the current zoom level.

    Viewport width and screen width

    Many sites set their viewport to "width=320, initial-scale=1" to fit precisely onto the iPhone display in portrait mode. As mentioned above, this caused problems when Fennec 1.0 endered these sites, especially in landscape mode. To fix this, Fennec 1.1 will expand the viewport width if necessary to fill the screen at the requested scale. This matches the behavior of Android and Mobile Safari, and is especially useful on large-screen devices like the iPad. (Allen Pike’s Choosing a viewport for iPad sites has a good explanation for web developers.)

    For pages that set an initial or maximum scale, this means the width property actually translates into a minimum viewport width. For example, if your layout needs at least 500 pixels of width then you can use the following markup. When the screen is more than 500 pixels wide, the browser will expand the viewport (rather than zoom in) to fit the screen:

    <meta name="viewport" content="width=500, initial-scale=1"/>

    Fennec 1.1 also adds support for minimum-scale, maximum-scale, and user-scalable, with defaults and limits similar to Safari’s. These properties affect the initial scale and width, as well as limiting changes in zoom level.

    Mobile browsers handle orientation changes slightly differently. For example, Mobile Safari often just zooms the page when changing from portrait to landscape, instead of laying out the page as it would if originally loaded in landscape. If web developers want their scale settings to remain consistent when switching orientations on the iPhone, they must add a maximum-scale value to prevent this zooming, which has the sometimes-unwanted side effect of preventing users from zooming in:

    <meta name="viewport" content="initial-scale=1, maximum-scale=1">

    This is not necessary in Fennec; when the device changes orientation, Fennec updates the viewport size, the page layout, and JavaScript/CSS properties like device-width, based on its new “window” dimensions.

    Standards

    There is clearly demand for the viewport meta tag, since it is supported by most popular mobile browsers and used by thousands of web sites. It would be good to have a true standard for web pages to control viewport properties. According to the HTML5 spec, extensions to the meta element should first be registered on the WHATWG wiki and then go through the W3C standards process. If this happens, then we at Mozilla will work to make sure we can implement any changes made during standardization.