1. Developer Tools in Firefox Aurora 10

    The Preview You Can Use Now

    Mozilla is building a collection of stable, fast and usable developer tools that ship with the browser. I’d like to introduce a collection of improvements that are scheduled to be released in final form on January 31, 2012.

    But, you can get them now by downloading the Firefox Aurora channel. I personally find Aurora builds to be quite stable and usable for general browsing and web development. Give it a try and see what you think. You can install Aurora alongside your stable release of Firefox.

    The New Page Inspector

    Inspect Element Context Menu

    Using built-in tools, you can now peek into your page’s structure and layout. Choose “Inspect” from the “Web Developer” menu, or press the handy ctrl-shift-I (cmd-shift-I on Mac) keyboard shortcut, and you can visually select the page element that is of interest to you.

    You’ll also find a new “Inspect Element” context menu item that lets you immediately select the element that’s under your cursor.

    When you’re inspecting a page, you’ll see something like this:

    We overlay the page to highlight the element that you’re working with (1). The highlighter also shows you the tag, ID and classes associated with the page element you’re viewing.

    At the bottom of the window, there’s a toolbar that gives you options for changing or working with the selected element. Starting from the left, there’s a close button to close the page inspector and return to normal browsing. The “Inspect” button toggles visual selection mode so that you can highlight another element. ProTip: pressing the ESC key also switches modes.

    We call the next part of the toolbar the “breadcrumbs”. They show you where you are in the HTML structure and let you quickly switch to another element. The selected element is the dark “pushed” button. To the left of it are its parents, and to the right one of its children. Just click one of the buttons to move between the page elements. If you click and hold a button, you get a menu that lets you select from the siblings of the element listed on the button. The breadcrumbs make navigation quick without taking up much of your screen.

    HTML

    Sometimes looking at the HTML representation of a page is the quickest way to figure out what’s going on. Click the HTML button and that’s the view you’ll get. There’s a resizer on the right side of the toolbar to set just how much space you want for the HTML view. Also, clicking on a node in the HTML view will select that element for further inspection. ProTip: ctrl-H toggles the HTML view.

    Styles

    Last, but definitely not least, is the Style view. This lets you dive in, explore and experiment with your CSS. It offers two separate views of the CSS attached to the selected element: a CSS rules-based view (left, above), and a properties-based view (right, above).

    The rules view is organized much like your stylesheets, showing all of the rules that apply to the element and all of those properties that those rules give you. Properties that are overridden are crossed out. You can toggle any single property easily using the checkbox to the left of it. A single click on a property name or value lets you edit it and see the results immediately on the page. If you click anywhere on the line with the brace at the bottom of the rule, you can add a new property there.

    On a page with lots of styles, you sometimes just want to find out what the font-size is set to. That’s where the property view comes in. You can expand the “font-size” property and see how its set and which stylesheet set it. By default, only styles that are set in your stylesheets will be displayed (so you don’t get browser defaults listed). If you have a lot of properties listed, as you might if you use a reset stylesheet, you can quickly find what you’re looking for by typing in the search box.

    ctrl-S toggles the Style view.

    Web Console + Page Inspector: Great Together

    The Web Console is available whenever you want it, even when you’re using the page inspector. If you have an element selected, that element is available to JavaScript in the console using the variable $0.

    Scratchpad

    The Scratchpad feature, which we released in August, gives you a very friendly way to experiment with JavaScript. Rather than being confined to a small input box, you get a whole editor window to work with. Now, Scratchpad uses the Orion code editor to provide syntax highlighting, better indentation and other features you’d expect from a modern code editor.

    Scratchpad is now wired into Firefox’s “session restore” feature. This means that you can try out a bunch of code in Scratchpad and if you restart Firefox, restoring your session will also bring back your Scratchpad. Of course, you can always save and reload your Scratchpad files, just as you could before.

    If you are only doing web development, we’ve streamlined the user interface. If you’re doing Firefox add-on development, you owe it to yourself to set devtools.chrome.enabled to true in about:config. That setting allows Scratchpad to run code in a privileged browser context and not just against the current web page.

    The console Object

    We’ve been building out the console object that you call from your JavaScript code or use at the Web Console’s JavaScript input. It is now in line with the de facto standard, implementing the methods that are standard across browsers. Firebug has a couple of others that we don’t implement yet (console.table, console.profile, console.dirxml), but the commonly used methods are there.

    More Is On The Way

    All of these features are available now in Firefox Aurora builds. We’re working on getting more new features together for you for the next Aurora.

    Check out our Get Involved page to see how you can provide feedback and help make these tools even better.


    Footnotes:

    1. Other web developer tools make changes to your page (for example, adding a class) to make the selected element visible. Firefox’s highlighter does its work without making any changes to your content .↩

  2. Firefox – tons of tools for web developers!

    One of the goals of Firefox have always been to make the lives of web developers as easy and productive as possible, by providing tools and a very extensible web browser to enable people to create amazing things. The idea here is to list a lot of the tools and options available to you as web developers using Firefox.

    Continued…

  3. Announcing Firefox Aurora 10

    We’re happy to announce the availability of Aurora 10.
    (Download and Test Aurora 10)

    In additional to the normal improvements that you’ve come to expect like performance, security and bug fixes, Aurora 10 focuses in HTML5 enhancements.

    New additions

    Developer Tools

    Aurora 10 also implements incremental enhancements like IndexedDB setVersion API changes. Ongoing detailed attention to evolving specifications help to keep Firefox at the front of the Web revolution. (Read more about IndexedDB on MDN.)

    DOM

    • We now fire a “load” event on stylesheet linking when the sheet load finishes or “error” if the load fails.
    • We turn the POSTDATA prompt into an information page (when navigating in session history).
    • We only forward event attributes on body/frameset to the window if we also forward the corresponding on* property.
    • We no longer allow more than one call to window.open() when we allow popups.
    • We fixed a bug where a success callback never fired when a position update is triggered after getCurrentPosition().
    • We removed replaceWholeText().
    • We fixed an error with createPattern(zero-size canvas).
    • We now handle putImageData(nonfinite) correctly.
    • We now throw INVALID_STATE_ERR when dispatching uninitialized events.
    • We’ve made Document.documentURI readonly.
    • We fixed document.importNode to comply with optional argument omitted.

    Web workers

    • We now allow data URLs.
    • We implemented event.stopImmediatePropagation in workers.
    • We made XHR2 response/responseType work in Web Workers.

    Graphics

    • We implement the WebGL OES_standard_derivatives extension.
    • We implement minimal-capabilities WebGL mode.

    JavaScript

    • The function caller property no longer skips over eval frames.
    • We fixed E4X syntax so that it is not accepted in ES5 strict mode.
    • weakmap.set no longer returns itself instead of undefined.
    • We implemented the battery API.

    Offline: IndexedDB enhancements

    • IndexedDB setVersion API changes
    • Added support for IDBObjectStore/IDBIndex.count
    • Various methods accept both keys and KeyRanges.
    • Added support for IDBCursor.advance.
    • Implemented deleteDatabase.
    • objectStoreNames are no longer updated on closed databases when another connection adds or removes object stores
    • IDBObjectStore.delete and IDBCursor.delete now return undefined.
    • No longer throws an error if there are unknown properties in the options objects to createObjectStore/createIndex.
    • We now the errorCode to “ABORT_ERR” for all pending requests when IDBTransaction.abort() is called.
    • Fixed the sort order for indexes.

    Layout

    • We have updated the current rule for handling malformed media queries.
    • We now support the HTML5 <bdi> element and CSS property unicode-bidi: isolate.
    • The CSS3 implementation now supports unicode-bidi: plaintext.

    Media

    • Implemented Document.mozFullScreenEnabled.
    • Enabled the DOM full-screen API on desktop Firefox by default.
  4. HTML5 context menus in Firefox (Screencast and Code)

    You may not know it, but the HTML5 specifications go beyond what we put in the pages and also define how parts of the browser should become available to developers with HTML, CSS and JavaScript. One of these parts of the specs are context menus, or “right click menus”. Using HTML5 and a menu element you can add new options to these without having to write a browser add-on. In Firefox 8 (the current one) we have support for those. See the following screencast for a context menu demo.

    The image example is pretty simple and was actually written by Paul Rouget as a demo in the original Firefox bug request. The main core is the HTML of it:

    <section id="noninteractive" contextmenu="imagemenu">
     
      <img src="html5.png" alt="HTML5" id="menudemo">
     
        <menu type="context" id="imagemenu">
          <menuitem label="rotate" onclick="rotate()"
                    icon="arrow_rotate_clockwise.png">
          </menuitem>
          <menuitem label="resize" onclick="resize()"
                    icon="image-resize.png">
          </menuitem>
          <menu label="share">
            <menuitem label="twitter" onclick="alert('not yet')"></menuitem>
            <menuitem label="facebook" onclick="alert('not yet')"></menuitem>
          </menu>
        </menu>
     
    </section>

    As you can see you link the menu element to an element via its ID. The contextmenu attribute then points to this one. Each menu can have several menuitems. Each of those gets a textual label and a possible icon. You can also nest menu elements to create multiple layer menus. Here, we add inline onclick handlers to point to different JavaScript functions to call when the menu item gets activated. The resulting context menu looks like this:

    image with a context menu

    The functionality is simple, all the rotate() and resize() functions do is add class names to the image using querySelector and classList:

    function rotate() {
      document.querySelector('#menudemo').classList.toggle('rotate'); 
    }
    function resize() {   
      document.querySelector('#menudemo').classList.toggle('resize'); 
    }

    The real effect is in CSS transforms and transitions. As the image has an ID of menudemo here is what is needed in CSS to rotate and resize:

    #menudemo { 
      -moz-transition: 0.2s; 
      width:200px;
    }
    #menudemo.rotate { 
      -moz-transform: rotate(90deg); 
    }
    #menudemo.resize { 
      -moz-transform: scale(0.7); 
    }
    #menudemo.resize.rotate { 
      -moz-transform: scale(0.7) rotate(90deg); 
    }

    Notice that in a real product we should of course add the other browser prefixes and go prefix-less but as the functionality now only works in Firefox, this is enough for this demo.

    Detecting support and visual hinting

    Now, as this is extending the normal user offerings in the browser we need to make it obvious that there is a right-click menu available. In CSS3, there is a context-menu cursor available to us. When context menus are available, this should be shown:

    .contextmenu #menudemo, .contextmenu .demo {
      cursor: context-menu;
    }

    We test the browser for support by checking for contextmenu on the body element and for HTMLMenuItemElement in the window (this has been added as a pull request to Modernizr, too).

    if ('contextMenu' in document.body && 'HTMLMenuItemElement' in window) {
      document.documentElement.classList.add('contextmenu');
    } else {
      return;
    }

    Wouldn’t HTMLMenuItemElement be enough? Yes, but a real context menu should only offer functionality when it is sensible, and that is where contextMenu comes in.

    Turning menuitems on and off depending on functionality

    As a slightly more complex example, let’s add a “count words” functionality to the document. For this, we generate a counter element that will become a tooltip when the words were counted:

    var counter = document.createElement('span');
    counter.id = 'counter';
    counter.className = 'hide';
    document.body.appendChild(counter);
     
    counter.addEventListener('click', function(ev){
      this.className = 'hide';
    },false);

    This one is hidden by default and becomes visible when the hide class is removed. To make it smooth, we use a transition:

    #counter{
      position: absolute;
      background: rgba(0,0,0,0.7);
      padding:.5em 1em;
      color: #fff;
      font-weight:bold;
      border-radius: 5px;
      -moz-transition: opacity 0.4s;
    }
    #counter.hide{
      opacity: 0;
    }

    We start with two sections with context menus:

    <section id="noninteractive" contextmenu="countmenu">
      <menu type="context" id="countmenu">
          <menuitem class="wordcount" label="count words"></menuitem>
      </menu>
    </section>
     
    <section id="interactive" contextmenu="countmenuinteractive">
      <menu type="context" id="countmenuinteractive">
          <menuitem class="wordcount" label="count words"></menuitem>
      </menu>
    </section>

    We then loop through all the menuitems with the class wordcount and apply the functionality.

    var wordcountmenus = document.querySelectorAll('.wordcount'),
        i = wordcountmenus.length;
     
    while (i--) {
      wordcountmenus[i].addEventListener('click', function(ev){
        // add functionality 
      }, false);
    }

    We need to find out what has been selected in the page. We do this by using getSelection() and splitting its string version at whitespace. We then show the counter by removing the hide class name.

    var wordcountmenus = document.querySelectorAll('.wordcount'),
        i = wordcountmenus.length;
     
    while (i--) {
      wordcountmenus[i].addEventListener('click', function(ev){
        var text = document.getSelection(),
            count = text.toString().split(/\s/).length;
        counter.innerHTML = count + ' words';
        counter.className = '';
      }, false);
    }

    You can see this in action in the second context menu demo. Now, the issue with this (as explained in the screencast) is that it always counts the words, regardless of the user having selected some text. What we want is the menu only to be active when there is text selected.

    context menu item available or not available depending on selection

    So in order to make our menu only become available when it makes sense we check if there is a selection in the document. Every context menu fires an event called contextmenu when it opens. So all we need to do is to subscribe to this event.

    When something is selected in the document document.getSelection().isCollapsed is true. Otherwise it is false, so all we need to do is to enable or disable the menu item accordingly:

    document.querySelector('#interactive').addEventListener(
      'contextmenu', function(ev) {
        this.querySelector('.wordcount').disabled =
        document.getSelection().isCollapsed;  
      },
    false);

    The last thing to solve is the position of the mouse to position the counter element. As the menu selection event doesn’t give us the mouse position we need to add a contextmenu handler to the whole document that positions the counter invisibly behind the menu when it is opened:

    document.body.addEventListener(
      'contextmenu', function(ev) {
        counter.style.left = ev.pageX + 'px';
        counter.style.top = ev.pageY + 'px';
        counter.className = 'hide';
      }, 
    false);

    Further reading and resources

  5. Want to go to Full Frontal in Brighton, England this Friday? We got tickets!

    photo by Lily

    Full Frontal is a JavaScript centric conference in Brighton, England on the 11/11/11. The simplest way to describe it is “a splendid kick into your lower back side” event when it comes to what’s hot and amazing int he world of scripting.

    The Mozilla Developer Network has 3 tickets to give out, one of which also entitles you to attend the speakers dinner the day before the conference. Tickets for the conference are gone, so here is your last chance.

    If you want to take part in this, you need to be able to get to Brighton, England on the 11th and be open to also come on the 10th for the speaker’s dinner (one of you). Please say if you can’t come on the 10th – you can still win a ticket. We will need your name for the organisers to put on the list.

    First and foremost though, in order to win a ticket add a comment here why you deserve to get a Mozilla ticket and what you can do as a thank you to help the open web.

    The best reasons and offers will get the tickets. We will announce the pick on the 9th here and contact you so please leave a valid email in the comment (this will not be shown to the public).

    For extra brownie points, why not tell us what new initiatives of Mozilla get you most excited and what we could be doing to make them a reality faster.

    See you in Brighton, it rocks!

    We picked the winners, now! Let’s get full frontal!

  6. insertAdjacentHTML() Enables Faster HTML Snippet Injection

    The following is a guest post by Henri Sivonen:

    In Firefox 8, we’ve added support for insertAdjacentHTML(). It’s an ancient feature of Internet Explorer that has recently been formalized in HTML5 and then spun out into the DOM Parsing specification. The bad news is that Firefox is the last major browser to implement this feature. The good news is that since other major browsers implement it already, you can start using it unconditionally as soon as the Firefox 8 update has been rolled out to users.

    Basic Usage

    insertAdjacentHTML(position, markup) is a method on HTMLElement DOM nodes. It takes two string arguments. The first argument is one of "beforebegin", "afterbegin", "beforeend", or "afterend" and gives the insertion point relative to the node that insertAdjacentHTML() is invoked on. The second argument is a string containing HTML markup that gets parsed as an HTML fragment (similar to a string assigned to innerHTML) and inserted to the position given by the first argument.

    If the node that insertAdjacentHTML() is invoked on is a p element
    with the text content “foo”, the insertion points would be where the comments are in the following snippet:

    <!-- beforebegin --><p><!-- afterbegin -->foo<!--
    beforeend --></p><!-- afterend -->

    The "beforebegin" and "afterend" positions work only if
    the node is in a tree and has an element parent.

    For example, consider the following code:

    <div id=container><p id=para>foo</p></div>
    <script>
      document.getElementById("para").insertAdjacentHTML("beforeend", "<span>bar</span>");
      console.log(document.getElementById("container").innerHTML);
    </script>

    This code produces this log output:

    <p id="para">foo<span>bar</span></p>

    Well, that does not look particularly special. In fact, it looks like something that could have been done using plain old innerHTML. So why bother with insertAdjacentHTML() when element.innerHTML += "markup"; already works?

    There are two reasons.

    • insertAdjacentHTML() doesn’t corrupt what’s already in the DOM.
    • insertAdjacentHTML() is faster.

    Avoiding DOM corruption

    Let’s consider the DOM corruption issue first. When you do element.innerHTML += "markup";, the browser does the following:

    1. It gets the value of innerHTML by serializing the descendants of element.
    2. It appends the right hand side of += to the string.
    3. It removes the children of element.
    4. It parses the new string that contains the serialization of the old descendants followed by some new markup.

    The old descendants might have been script-inserted to form a subtree that doesn’t round-trip when serialized as HTML and reparsed. In that case, after the operation, the tree would have a different shape even for the “old” parts. (For example, if element had a p child which in turn had a div child, the subtree wouldn’t round-trip.) Furthermore, even if serializing and reparsing resulted in a same-looking tree, the nodes created by the parser would be different nodes than the nodes that were children of element at first. Thus, if other parts of the JavaScript program were holding references to descendants of element, after element.innerHTML += "markup"; had been executed, those references would point to detached nodes and element would have new similar but different descendants.

    When additional content is inserted using insertAdjacentHTML(), the existing nodes stay in place.

    Better performance

    Serializing and reparsing is also what leads to performance problems with the element.innerHTML += "markup"; pattern. Each time some more content is appended, all the existing content in element gets serialized and reparsed. This means that appending gets slower and slower, because each time there more and more previous content to serialize and reparse.

    Using insertAdjacentHTML() can make a big difference. For testing purposes, I started with an empty div and ran a loop that tried to append as many tweets as possible to the div in five seconds. A tweet is actually rather large when you count all the mark-up that implements @mention linkification, the name of the tweeter, retweet and favoriting UI, etc. It weighs about 1600 characters of HTML source—most of it mark-up.

    On the computer that I used for testing, the innerHTML way of appending managed to append only slightly over 200 tweets in five full seconds. In contrast, the insertAdjacentHTML("beforeend", ...) way of appending managed to append almost 30,000 tweets in 5 seconds. (Yes, that’s hundreds versus tens of thousands.) Obviously, real Web apps should never block the event loop for five seconds—this is just for benchmark purposes. However, this illustrates how the innerHTML way of appending becomes notably slower as more and more content accumulates to be serialized and reparsed each time.

    At this point, some readers might wonder if insertAdjacentHTML() offers any benefit over createContextualFragment(). After all, conceptually insertAdjacentHTML() creates a fragment and inserts it.

    Using createContextualFragment(), my test manages only slightly over 25,000 tweets in five seconds, while using insertAdjacentHTML() manages slightly under 30,000. This is because Gecko accelerates insertAdjacentHTML() when the insertion point has no next sibling (only for HTML though—not for XML so far). The "beforeend" insertion point never has a next sibling and is always accelerated (for HTML). The "beforebegin" insertion point always has a next sibling (the node that insertAdjacentHTML() was invoked on) and is never accelerated. For "afterbegin" and "afterend", whether the operation is accelerated depends on the situation.

    In conclusion, you can make your Web app perform better by using element.insertAdjacentHTML("beforeend", "markup"); where you currently use element.innerHTML += "markup";.

  7. Screencast: BrowserID login flow on OpenPhoto.me

    BrowserID is an initiative to provide the web with a better way to sign in. The web is a connected collection of resources and you should not have to have a user name and password for each of them when you could use the web instead.

    Today we show you a screencast of how easy BrowserID makes it to login to a web site. For this, we’ll look at how the login flow for an existing BrowserID user works the first time they log in on a new website. Our example website is OpenPhoto, a hot new photo sharing app that keeps users in control of their data.

    Screencast of logging into OpenPhoto with BrowserID

    Get involved:

    BrowserID needs your help to grow and become a weapon of choice in the fight against insecure and annoying login systems. The great thing is that now is the time where you can be part of this.

  8. Webinar: IndexedDB with Jonas Sicking

    Update 2011-12-20: The video recording of this webinar is now available:

    IndexedDB is the emerging standard for structured client-side data storage. The IndexedDB standard is supported by current versions of Firefox and Chrome, and support for it is expected in Internet Explorer 10.

    With this growing maturity and support, it’s time to start experimenting with what IndexedDB can do for Web applications. Working with IndexedDB requires a shift in mindset for many Web developers, as it is more similar to “NoSQL” systems like CouchDB or MongoDB than to traditional relational databases.

    IndexedDB will be the theme for December’s MDN DevDerby. And to kick off the theme for the month, on December 1st, we’re offering an MDN Webinar on IndexedDB with Jonas Sicking, one of the editors of the IndexedDB draft standard and one of the implementors of IndexedDB in Gecko.

    When
    December 1st, at 9:00 a.m. US Pacific Time (17:00 UTC). Add this event to your Google calendar:
    Where
    Air Mozilla, with text chat on #airmozilla on irc.mozilla.org. (There’s an IRC widget on the Air Mozilla page if you need it.)

    We’ll record this session for those who can’t attend (or can’t use Flash, which is currently used by Air Mozilla for live streaming video).

    We’d like to get a rough estimate of how many people will be attending. If you happen to use Plancast, and you plan to attend the seminar, please join the event on Plancast.

  9. Using CORS to load WebGL textures from cross-domain images

    In Firefox, as well as in Chrome, it is now possible to load cross-domain images into WebGL textures, if they have been approved by CORS.

    Most prominently, this feature allows for impressive 3D mapping applications such as Google MapsGL and Nokia Maps 3D.

    What happened

    Earlier this year, the Editor’s Draft WebGL specification got updated in response to a security concern. The additions were:

    1. A mandatory clause disallowing usage of cross-domain elements as WebGL textures in the general case.
    2. A non-normative clause specifically allowing cross-domain elements that have CORS approval. For that occasion, the HTML specification on the <img> element got updated to add a new crossorigin attribute.

    The first got implemented in Firefox 5, the second is now in Firefox 8.

    How to use this feature

    There are two CORS modes: “anonymous” and “use-credentials”. We’ll focus on “anonymous” as it’s the common case. A great example of images served with anonymous CORS is Google Maps imagery, such as:

    http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0

    In order to load it with CORS as a WebGL texture, we set the crossOrigin attribute on it:

    var earthImage = new Image();
    earthImage.crossOrigin = "anonymous";

    Now we load it as usual:

        earthImage.onload = function() {
          // whatever you usually to do load WebGL textures
        };
        earthImage.src = "http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0";

    That’s it! Aside from setting the crossOrigin attribute, we didn’t have to do anything. Here is the full self-contained example.

    The HTTP headers

    If we study the HTTP headers for this image (using, for example, Firefox’s Web Console), we find that the Request Headers contain

    Origin: null

    which is the effect of having set this crossOrigin attribute on the img element. And the Response Headers contain

    Access-Control-Allow-Origin: null

    which is the effect of the server supporting CORS for this file.

    Doing this in HTML

    Of course, one could also set this attribute in HTML, in which case it’s case-insensitive:

    <img src="http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0" crossorigin="anonymous">

    And since “anonymous” is both the missing-value-default and the invalid-value-default for the crossorigin attribute, we can pass any invalid value for it, or even just omit its value:

    <img src="http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0" crossorigin>

    Coming soon: CORS approval for Canvas 2D drawImage

    What if you first draw a CORS-approved cross-domain image onto a 2D
    canvas, and then use that canvas as the source of a WebGL texture? The
    good news is that this will work in Firefox 9, which is hitting the Beta
    channel soon. This fix means that demos like this will work really
    nicely in Firefox 9.

  10. Webinar: Canvas with Rob Hawkes

    Update 2011-11-10: Video of this webinar is now available:

    You can download the code that Rob demos in the webinar.

    You might also check out the recording of the webinar created by BigBlueButton. It syncs the audio with the slides and chat window using Popcorn.js. On the downside, BBB starts recording as soon as anyone joins the conference audio bridge, which in this case happened an hour before the webinar started. Fast-forward to time 58:20 for the start of the webinar.

    Please join us on Tuesday, November 8th at 17:00 UTC (convert to your local time) for a webinar on using the Canvas API, with our own Rob Hawkes, author of Foundation HTML5 Canvas.

    Canvas is the topic for the November Dev Derby. Rob is planning to show how to make an image editor for avatars using Canvas. Spark your imagination with the webinar, create some new and amazing use of Canvas, and submit it to the Dev Derby.

    We will use BigBlueButton for web-conferencing, and will avoid using the feature that led to the server problems with the September webinar. We will be recording the session, and I promise to double- and triple-check the recording set-up in advance :-)

    Add this event to your calendar:

    We’d like to get a rough estimate of how many people will be attending. If you happen to use Plancast, and you plan to attend the seminar, please join the event on Plancast.

    To join the webinar:

    1. Go to the BigBlueButton server for Mozilla.
    2. For Full Name, enter your name.
    3. Select “Mozilla Developer Network” in the Room list.
    4. For Password, enter MDNHacks.
    5. Note: Big Blue Button uses Flash, so make sure you have the latest version installed, especially if you are running Mac OS X Lion.