Mozilla

Articles by Chris Heilmann

Sort by:

View:

  1. HTML5 mythbusting

    The ongoing discussion about the “readiness” of HTML5 is based on a lot of false assumptions. These lead to myths about HTML5 that get uttered once and then continuously repeated – a lot of times without checking their validity at all.

    HTML5 doesn’t perform?

    The big thing everybody who wants to talk about the problems with HTML5 is performance. The main problem here is that almost every single comparison misses the fact that you are comparing apples and pears (no pun intended).

    Comparing an HTML5 application’s performance with a native App is comparing a tailored suit with one bought in a shop. Of course the tailored suit will fit you like a glove and looks amazing but if you ever want to sell it or hand it over to someone else you are out of luck. It will not be the same for the next person.

    IMG_4197.jpg

    That is what native Apps are – they are built and optimized for one single environment and purpose and are fixed in their state – more on that later.

    HTML5, on the other hand by its very definition is a web technology that should run independent of environment, display or technology. It has to be as flexible as possible in order to be a success on the web. In its very definition the web is for everybody, not just for a small group of lucky people who can afford a very expensive piece of hardware and are happy to get locked into a fixed environment governed by a single company.

    Native applications need to be written for every single device and every new platform from scratch whereas an HTML5 App allows you to support mobiles, tablets and desktops with the same product. Instead of having fixed dimensions and functionality an HTML5 App can test what is supported and improve the experience for people on faster and newer devices whilst not locking out others that can not buy yet another phone.

    Native Apps on the other hand do in a lot of cases need an upgrade and force the end user to buy new hardware or they’ll not get the product at all. From a flexibility point of view, HTML5 Apps perform admirably whilst native applications make you dependent on your hardware and leave you stranded when there is an upgrade you can’t afford or don’t want to make. A great example of this is the current switch from Apple to their own maps on iOS. Many end users are unhappy and would prefer to keep using Google Maps but can not.


    HexGL – a WebGL powered racing game

    Seeing that HTML5 is perfectly capable on Desktop to exceed in performance, from scrolling performance to analyzing and changing video on the fly up to running full 3D games at a very high frame rate and have high speed racing games we have to ask ourselves where the problem with its performance lies.

    The answer is hardware access. HTML5 applications are treated by mobile hardware developed for iOS and Android as second class citizens and don’t get access to the parts that allow for peak performance. A web view in iOS is hindered by the operating system to perform as fast as a native App although it uses the same principles. On Android both Chrome and Firefox show how fast browsers can perform whereas the stock browser crawls along in comparison.

    The stock browser on Android reminds us of the Internet Explorer of the 90s which threatened to be set in stone for a long time and hinder the world wide web from evolving – the very reason Mozilla and Firefox came into existence.

    In essence HTML5 is a Formula 1 car that has to drive on a dirt road whilst dragging a lot of extra payload given to it by the operating system without a chance to work around that – for now.

    HTML5 can not be monetized?

    HTML5 is a technology stack based on open web technologies. Saying that HTML5 has no monetization model is like saying the web can not be monetized (which is especially ironic when this is written on news sites that show ads).

    Whilst on the first glance a closed App-market is a simple way to sell your products there is a lot of hype about their success and in reality not many developers manage to make a living with a single app on closed App markets. As discovery and find-ability is getting increasingly harder in App markets a lot of developers don’t build one App but hundreds of the same App (talking dog, talking cat, talking donkey…) as it is all about being found quickly and being on the first page of search results in the market.

    This is where closed App markets with native Apps are a real disadvantage for developers: Apps don’t have an address on the web (URL) and can not be found outside the market. You need to manually submit each of the Apps in each of the markets, abide to their review and submission process and can not update your App easily without suffering outages in your offering.

    An HTML5 App is on the web and has a URL, it can also get packaged up with products like Adobe PhoneGap to become a native application for iOS or Android. The other way around is not possible.

    In the long term that begs the question what is the better strategy for developers: betting on one closed environment that can pull your product any time it wants or distributing over a world-wide, open distribution network and cover the closed shops as well?

    Many apps in the Android and iOS store are actually HTML5 and got converted using PhoneGap. The biggest story about this was the Financial Times releasing their app as HTML5 and making a better profit than with the native one. And more recently the New York Times announced it was following suit with its Web app.

    HTML5 can not be offline?

    As HTML5 is a web technology stack the knee-jerk reaction is thinking that you would have to be online all the time to use them. This is plain wrong. There are many ways to store content offline in a HTML5 application. The simplest way is the Web Storage API which is supported across all modern browsers (excluding Opera mini which is a special case as it sends content via a cloud service and has its own storage tools). You can also store the application itself offline using AppCache which is supported by all but Internet Explorer. If you have more complex data to store than Web Storage provides you can use either IndexedDB (for Chrome and Firefox) or WebSQL (for iOS and Safari). To work around the issues there are libraries like Lawnchair available to make it easy for developers to use.

    HTML5 has no development environment?

    One concern often mentioned is that HTML5 lacks in tooling for developers. Strangely enough you never hear that argument from developers but from people who want to buy software to make their developers more effective instead of letting them decide what makes them effective.

    HTML5 development at its core is web development and there is a quite amazingly practical development environment for that available. Again, the main issue is a misunderstanding of the web. You do not build a product that looks and performs the same everywhere – this would rob the web of its core strengths. You build a product that works for everybody and excels on a target platform. Therefore your development environment is a set of tools, not a single one doing everything for you. Depending on what you build you choose to use many of them or just one.

    The very success of the web as a media is based on the fact that you do not need to be a developer to put content out – you can use a blogging platform, a CMS or even a simple text editor that comes with your operating system to start your first HTML page. As you progress in your career as a developer you find more and more tools you like and get comfortable and effective with but there is no one tool to rule them all. Some developers prefer IDEs like Visual Studio, or Eclipse. Others want a WYSIWYG style editor like Dreamweaver but the largest part of web developers will have a text editor or other of some sorts. From Sublime Text, Notepad++ up to VIM or emacs on a Linux computer, all of these are tools that can be used and are used by millions of developers daily to build web content.

    When it comes to debugging and testing web developers are lucky these days as the piece of software our end users have to see what we build – the browser – is also the debugging and testing environment. Starting with Firefox having Firebug as an add-on to see changes live and change things on the fly, followed by Opera’s Dragonfly and Safari and Chrome’s Devtools, all browsers now also have a lot of functionality that is there especially for developers. Firefox’s new developer tools go even further and instead of simply being a debugging environment are a set of tools in themselves that developers can extend to their needs.

    Remote debugging is another option we have now. This means we can as developers change applications running on a phone on our development computers instead of having to write them, send them to the phone, install them, test them, find a mistake and repeat. This speeds up development time significantly.


    Remote debugging in Firefox

    For the more visual developers Adobe lately released their Edge suite which brings WYSIWYG style development to HTML5, including drag and drop from Photoshop. Adobe’s Edge Inspect and PhoneGap makes it easy to test on several devices at once and send HTML5 Apps as packaged native Apps to iOS and Android.

    In terms of deployment and packaging Google just released their Yeoman project which makes it dead easy for web developers to package and deploy their web products as applications with all the necessary steps to make them perform well.

    All in all there is no fixed development environment for HTML5 as that would neuter the platform – this is the web, you can pick and choose what suits you most.

    Things HTML5 can do that native Apps can not

    In essence a lot of the myths of HTML5 are based on the fact that the comparison was between something explicitly built for the platform it was tested on versus something that is also supported on it. Like comparing the performance of speedboat and a hovercraft would result in the same predictable outcome. The more interesting question is what makes HTML5 great for developers and end users, that native applications can or do not do:

    • Write once, deploy anywhere – HTML5 can run in browsers, on tablets and desktops and you can convert it to native code to support iOS and Android. This is not possible the other way around.
    • Share over the web – as HTML5 apps have a URL they can be shared over the web and found when you search the web. You don’t need to go to a market place and find it amongst the crowded, limited space but the same tricks how to promote other web content apply. The more people like and link to your app, the easier it will be found.
    • Built on agreed, multi-vendor standards – HTML5 is a group effort of the companies that make the web what it is now, not a single vendor that can go into a direction you are not happy with
    • Millions of developers – everybody who built something for the web in the last years is ready to write apps. It is not a small, specialized community any longer
    • Consumption and development tool are the same thing – all you need to get started is a text editor and a browser
    • Small, atomic updates – if a native app needs an upgrade, the whole App needs to get downloaded again (new level of Angry Birds? Here are 23MB over your 3G connection). HTML5 apps can download data as needed and store it offline, thus making updates much less painful.
    • Simple functionality upgrade – native apps need to ask you for access to hardware when you install them and can not change later on which is why every app asks for access to everything upfront (which of course is a privacy/security risk). An HTML5 app can ask for access to hardware and data on demand without needing an update or re-installation.
    • Adaptation to the environment – an HTML5 app can use responsive design to give the best experience for the environment without having to change the code. You can switch from Desktop to mobile to tablet seamlessly without having to install a different App on each.

    Let’s see native Apps do that.

    Breaking the hardware lockout and making monetization easier

    The main reason why HTML5 is not the obvious choice for developers now is the above mentioned lockout when it comes to hardware. An iOS device does not allow different browser engines and does not allow HTML5 to access the camera, the address book, vibration, the phone or text messaging. In other words, everything that makes a mobile device interesting for developers and very necessary functionality for Apps.

    To work around this issue, Mozilla and a few others have created a set of APIs to define access to these in a standardized way called Web APIs. This allows every browser out there to get access to the hardware in a secure way and breaks the lockout.

    The first environment to implement these is the Firefox OS with devices being shipped next year. Using a Firefox OS phone you can build applications that have the same access to hardware native applications have. Developers have direct access to the hardware and thus can build much faster and – more importantly – much smaller Apps. For the end user the benefit is that the devices will be much cheaper and Firefox OS can run on very low specification hardware that can for example not be upgraded to the newest Android.

    In terms of monetization Mozilla is working on their own marketplace for HTML5 Apps which will not only allow HTML5 Apps to be submitted but also to be discovered on the web with a simple search. To make it easier for end users to buy applications we partner with mobile providers to allow for billing to the mobile contract. This allows end users without a credit card to also buy Apps and join the mobile web revolution.

    How far is HTML5?

    All in all HTML5 is going leaps and bounds to be a very interesting and reliable platform for app developers. The main barriers we have to remove is the hardware access and with the WebAPI work and systems like PhoneGap to get us access these are much less of a stopper than we anticipated.

    The benefits of HTML5 over native apps mentioned above should be reason enough for developers to get involved and start with HTML5 instead of spending their time building a different code base for each platform. If all you want to support is one special platform you don’t need to go that way, but then it is also pointless to blame HTML5 issues for your decision.

    HTML5 development is independent of platform and browser. If you don’t embrace that idea you limit its potential. Historically closed platforms came and went and the web is still going strong and allows you to reach millions of users world-wide and allows you to start developing without asking anyone for permission or having to install a complex development environment. This was and is the main reason why people start working with the web. And nobody is locked out, so have a go.

  2. There is no simple solution for local storage

    TL;DR: we have to stop advocating localStorage as a great opportunity for storing data as it performs badly. Sadly enough the alternatives are not nearly as supported or simple to implement.

    When it comes to web development you will always encounter things that sound too good to be true. Sometimes they are good, and all that stops us from using them is our notion of being conspicuous about *everything* as developers. In a lot of cases, however, they really are not as good as they seem but we only find out after using them for a while that we are actually “doing it wrong”.

    One such case is local storage. There is a storage specification (falsely attributed to HTML5 in a lot of examples) with an incredibly simple API that was heralded as the cookie killer when it came out. All you have to do to store content on the user’s machine is to access the navigator.localStorage (or sessionStorage if you don’t need the data to be stored longer than the current browser session):

    localStorage.setItem( 'outofsight', 'my data' );
    console.log( localStorage.getItem( 'outofsight' ) ); // -> 'my data'

    This local storage solution has a few very tempting features for web developers:

    • It is dead simple
    • It uses strings for storage instead of complex databases (and you can store more complex data using JSON encoding)
    • It is well supported by browsers
    • It is endorsed by a lot of companies (and was heralded as amazing when iPhones came out)

    A few known issues with it are that there is no clean way to detect when you reach the limit of local storage and there is no cross-browser way to ask for more space. There are also more obscure issues around sessions and HTTPS, but that is just the tip of the iceberg.

    The main issue: terrible performance

    LocalStorage also has a lot of drawbacks that aren’t quite documented and certainly not covered as much in “HTML5 tutorials”. Especially performance oriented developers are very much against its use.

    When we covered localStorage a few weeks ago using it to store images and files in localStorage it kicked off a massive thread of comments and an even longer internal mailing list thread about the evils of localStorage. The main issues are:

    • localStorage is synchronous in nature, meaning when it loads it can block the main document from rendering
    • localStorage does file I/O meaning it writes to your hard drive, which can take long depending on what your system does (indexing, virus scanning…)
    • On a developer machine these issues can look deceptively minor as the operating system cached these requests – for an end user on the web they could mean a few seconds of waiting during which the web site stalls
    • In order to appear snappy, web browsers load the data into memory on the first request – which could mean a lot of memory use if lots of tabs do it
    • localStorage is persistent. If you don’t use a service or never visit a web site again, the data is still loaded when you start the browser

    This is covered in detail in a follow-up blog post by Taras Glek of the Mozilla performance team and also by Andrea Giammarchi of Nokia.

    In essence this means that a lot of articles saying you can use localStorage for better performance are just wrong.

    Alternatives

    Of course, browsers always offered ways to store local data, some you probably never heard of as shown by evercookie (I think my fave when it comes to the “evil genius with no real-world use” factor is the force-cached PNG image to be read out in canvas). In the internal discussions there was a massive thrust towards advocating IndexedDB for your solutions instead of localStorage. We then published an article how to store images and files in IndexedDB and found a few issues – most actually related to ease-of-use and user interaction:

    • IndexedDB is a full-fledged DB that requires all the steps a SQL DB needs to read and write data – there is no simple key/value layer like localStorage available
    • IndexedDB asks the user for permission to store data which can spook them
    • The browser support is not at all the same as localStorage, right now IndexedDB is supported in IE10, Firefox and Chrome and there are differences in their implementations
    • Safari, Opera, iOS, Opera Mobile, Android Browser favour WebSQL instead (which is yet another standard that has been officially deprecated by the W3C)

    As always when there are differences in implementation someone will come up with an abstraction layer to work around that. Parashuram Narasimhan does a great job with that – even providing a jQuery plugin. It feels wrong though that we as implementers have to use these. It is the HTML5 video debate of WebM vs. H264 all over again.

    Now what?

    There is no doubt that the real database solutions and their asynchronous nature are the better option in terms of performance. They are also more matured and don’t have the “shortcut hack” feeling of localStorage. On the other hand they are hard to use in comparison, we already have a lot of solutions out there using localStorage and asking the user to give us access to storing local files is unacceptable for some implementations in terms of UX.

    The answer is that there is no simple solution for storing data on the end users’ machines and we should stop advocating localStorage as a performance boost. What we have to find is a solution that makes everybody happy and doesn’t break the current implementations. This might prove hard to work around. Here are some ideas:

    • Build a polyfill library that overrides the localStorage API and stores the content in IndexedDB/WebSQL instead? This is dirty and doesn’t work around the issue of the user being asked for permission
    • Implement localStorage in an asynchronous fashion in browsers – actively disregarding the spec? (this could set a dangerous precedent though)
    • Change the localStorage spec to store asynchronously instead of synchronously? We could also extend it to have a proper getStorageSpace interface and allow for native JSON support
    • Define a new standard that allows browser vendors to map the new API to the existing supported API that matches the best for the use case?

    We need to fix this as it doesn’t make sense to store things locally and sacrifice performance at the same time. This is a great example of how new web standards give us much more power but also make us face issues we didn’t have to deal with before. With more access to the OS, we also have to tread more carefully.

  3. WebSocket disabled in Firefox 4

    Recent discoveries found that the protocol that Websocket works with is vulnerable to attacks. Adam Barth demonstrated some serious attacks against the protocol that could be used by an attacker to poison caches that sit in between the browser and the Internet.

    This is a serious threat to the Internet and Websocket and not a browser specific issue. The protocol vulnerabilities also affect Java and Flash solutions. In a web environment that could for example mean that a widely used JavaScript file – like Google analytics – could be replaced on a cache you go through with a malware file. Google would not be to blame and it would be hard for you to trace where the file is from as it will not be on your server. To avoid a lot of malware showing up without being easily traceable we need to fix the protocol.

    No Websocket support in Firefox 4 and Opera until the security issues are fixed

    That’s why we’ve decided to disable support for WebSocket in Firefox 4, starting with beta 8 due to a protocol-level security issue. Beta 7 of Firefox has support for the -76 version of the protocol, the same version that’s included with Chrome and Safari. Beta 8 of Firefox 4 will remove that support. Anne van Kesteren of Opera also announced that Opera are dropping Websocket support. We are confident that other browser developers will follow.

    What does this mean for developers?

    Right now, your Websocket solutions will not work in Firefox 4 final. Once we have a version of the protocol that we feel is secure and stable, we will include it in a release of Firefox – even a minor update release. The code will remain in the tree to help development, but will only be activated when a developer sets a hidden preference in Firefox (the same applies to Opera).

    If your code does proper object detection nothing should go wrong – when a user doesn’t have Websocket enabled the window.WebSocket property will not be available.

    Working on a fix

    Mozilla is still excited about what WebSocket offers and we’re working hard with the IETF on a new WebSocket protocol.

    Right now we are pushing the boundaries of what browsers can do for their users – this is what HTML5 is about.

    Whenever you push the boundaries of any technology you will run into issues. The great thing about our situation right now is that we can react quickly and swiftly to any issues arising and fix them before our end users are the ones who suffer. Making the whole world upgrade and patch a final browser is almost impossible which is why it makes sense to test and patch in betas and nightlies.

  4. CSS Variables in Firefox Nightly

    As reported by Cameron McCormack, Firefox Nightly (version 29) now supports CSS variables. You can get a quick overview in this short screencast:

    You can define variables in a context with a var- prefix and then implement them using the var() instruction. For example:

    :root {
      var-companyblue: #369; 
      var-lighterblue: powderblue;
    }
     
    h1 {
      color: var(companyblue);
    }
    h2 {
      color: var(lighterblue);
    }
    <h1>Header on page</h1>
    <h2>Subheader on page</h2>

    This defines the two variables companyblue and lighterblue for the root element of the document which results in (you can try it here using Firefox Nightly):

    Variables are scoped, which means you can overwrite them:

    :root {
      var-companyblue: #369;
      var-lighterblue: powderblue;
    }
    .partnerbadge {
      var-companyblue: #036;
      var-lighterblue: #cfc;
    }
     
    h1 {
      color: var(companyblue);
    }
    h2 {
      color: var(lighterblue);
    }
    <h1>Header on page</h1>
    <h2>Subheader on page</h2>
     
    <div class="partnerbadge">
      <h1>Header on page</h1>
      <h2>Subheader on page</h2>
    </div>

    Using these settings, headings inside an element with a class of partnerbadge will now get the other blue settings:

    Variables can be any value you want to define and you can use them like any other value, for example inside a calc() calculation. You can also reset them to other values, for example inside a media query. This example shows many of these possibilities.

    :root {
      var-companyblue: #369;
      var-lighterblue: powderblue;
      var-largemargin: 20px;  
      var-smallmargin: calc(var(largemargin) / 2);
      var-borderstyle: 5px solid #000;
      var-headersize: 24px;
    }
    .partnerbadge {
      var-companyblue: #036;
      var-lighterblue: #369;
      var-headersize: calc(var(headersize)/2);
      transition: 0.5s;
    }
     
    @media (max-width: 400px) {
      .partnerbadge {
         var-borderstyle: none;  
         background: #eee;
      }
    }
     
    /* Applying the variables */
    body {font-family: 'open sans', sans-serif;}
     
    h1 {
      color: var(companyblue);
      margin: var(largemargin) 0;
      font-size: var(headersize);
    }
    h2 {
      color: var(lighterblue);
      margin: var(smallmargin) 0;
      font-size: calc(var(headersize) - 5px);
    }
     
    .partnerbadge {
      padding: var(smallmargin) 10px;
      border: var(borderstyle);
    }

    Try resizing the window to less than 400 pixels to see the mediaQuery change in action.

    An initial implementation of CSS Variables has just landed in Firefox Nightly, which is currently at version 29 and after the February 3 merge, in Firefox Aurora. There are still a few parts of the specification which still need to be supported before the can go into the release cycle of Firefox Beta and Firefox. Cameron has the details on that:

    The only part of the specification that has not yet been implemented is the CSSVariableMap part, which provides an object that behaves like an ECMAScript Map, with get, set and other methods, to get the values of variables on a CSSStyleDeclaration. Note however that you can still get at them in the DOM by using the getPropertyValue and setProperty methods, as long as you use the full property names such as "var-theme-colour-1".

    The work for this feature was done in bug 773296, and my thanks to David Baron for doing the reviews there and to Emmanuele Bassi who did some initial work on the implementation. If you encounter any problems using the feature, please file a bug!

    For now, have fun playing with CSS variables in Nightly and tell us about issues you find.

  5. CSS 3D transformations in Firefox Nightly

    When the first 3D transformations in CSS got support on Webkit browsers people got incredibly excited about them. Now that they have matured we also support 3D CSS in Firefox. To see it for yourself, check out one of the latest nightly builds.

    You can see them in action in this demo of a rotating HTML5 logo and the screencast below:

    This means now that we need your support in trying out CSS 3D examples in Firefox and add other extensions than -webkit- to your CSS 3D products and demos. To show that this is possible, we took the well-known webkit-only “poster circle” demo and made it work with Firefox nightly by adding the -moz- (and of course the other prefixes and one set of instructions without browser prefixes). Here is a slight excerpt:

    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    -o-transform-style: preserve-3d;
    -ms-transform-style: preserve-3d;
    transform-style: preserve-3d;

    You can see this in action in the screencast below alongside Chrome and you try the demo out yourself. The slight jerkiness is actually my MacBook Air impersonating a starting jet every time I use ScreenFlow and not the browser.

    To celebrate the release and to show how CSS 3D can be applied as subtle effect, have a game of pairs using your favourite browsers (and a cat) :

    browser pairs

    Oleg Romashin also spent some time to convert a few CSS 3D demos to work with Mozilla and you can check the 3D city for more “wow”.

    If you are new to CSS 3D transformations here’s a good beginner course and a tool to create them.

    The rotating HTML5 logo demo also shows how you can check if the currently used browser supports 3D transforms. Instead of repeating the animation frames for all the prefixes we test in JavaScript and create the CSS on the fly:

    function checksupport() {
      var props = ['perspectiveProperty', 'WebkitPerspective',
                   'MozPerspective', 'OPerspective', 'msPerspective'],
          i = 0,
          support = false;
      while (props[i]) {
        if (props[i] in form.style) {
          support = true;
          pfx = props[i].replace('Perspective','');
          pfx = pfx.toLowerCase();
          break;
        }
        i++;
      } 
      return support;
    }
    if (checksupport()) {
      var s = '';
      styles = document.createElement('style');
      s += '#stage{-'+ pfx +'-perspective: 300px;}'+
           '#logo{-'+ pfx +'-transform-style: preserve-3d;position:relative;}'+  
           '#logo.spin{-'+ pfx +'-animation: spin 3s infinite linear;}'+
           '@-'+ pfx +'-keyframes spin {'+  
           '0% {'+ 
           '-'+ pfx +'-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);'+   
           '}'+
           '100% {'+   
           '-'+ pfx +'-transform: rotateX(0deg) rotateY(360deg)'+
           ' rotateZ(360deg);'+ 
           '}}';
      styles.innerHTML = s;
      document.querySelector('head').appendChild(styles);
    }

    For more information on creating your own pages that use 3D transformations, take a look at the draft specification

    As always, If you find any bugs, please report them at bugzilla.mozilla.org!

    So please reward our hard work bringing the third dimension to Firefox’s CSS engine by supporting and testing. Cheers!

  6. New Features of Firefox Developer Tools: Episode 25

    Firefox 25 was just uplifted to the Aurora release channel which means we are back to report about new features in Firefox Developer Tools.

    Here’s a summary of some of the most exciting new features, and to get the whole picture you can check the complete list of resolved bugzilla tickets.

    Black box libraries in the Debugger

    In modern web development, we often rely on libraries like JQuery, Ember, or Angular, and 99% of the time we can safely assume that they “just work”. We don’t care about the internal implementation of these libraries: we treat them like a black box. However, a library’s abstraction leaks during debugging sessions when you are forced to step through its stack frames in order to reach your own code. To alleviate this problem, we introduced black boxing: a feature where you can tell the debugger to ignore the details of selected sources.

    To black box a source, you can either mark them one at a time by disabling the little eyeball next to it in the sources list:
    eyeball

    Or you can black box many sources at once by bringing up the developer toolbar with Shift+F2 and using the dbg blackbox command:

    dbg blackbox --glob *-min.js[source]

    When a source is black boxed:

    • Any breakpoints it may have are disabled.
    • When “pause on exceptions” is enabled, the debugger won’t pause when an exception is thrown in the black boxed source; instead it will wait until (and if) the stack unwinds to a frame in a source that isn’t black boxed.
    • The debugger will skip through black boxed sources when stepping.

    To see this in action and learn more about the details, check out the black boxing screencast on YouTube.

    Replay and edit requests in the Network Monitor

    You can now debug a network request by modifying headers before resending it. Right-click on an existing request and select the “resend” context menu item:

    resend request

    Now you can tweak the HTTP method, URL, headers, and request body before sending the request off again:

    tweak

    CSS Autocompletion in the inspector

    Writing CSS in the inspector is now much easier as we enabled autocompletion of CSS properties and values.

    autocomplete

    What’s more, it even works on inline style attributes

    inline

    Aside: this feature was implemented by contributors Girish Sharma and Mina Almasry. If you want to take your tools into your own hands too, check out our wiki page on how to get involved with developer tools.

    Execute JS in the current paused frame

    One request we’ve heard repeatedly is the ability to execute JS from the webconsole in the scope of the current paused frame in the debugger rather than the global scope. This is now possible. Using the webconsole to execute JS in the current frame can make it much easier to debug your apps.

    Edit: The webconsole has actually been executing in the current frame since Firefox 23, in Firefox 25 the scratchpad will execute in the current frame as well.

    Import and export profiled data in the Profiler

    Hacking on a shared project and think you found a performance regression in some bit of code owned by one of your friends? Don’t just file a github issue with steps to reproduce the slowness, export and attach a profile of the code that shows exactly how much slowness there is, and where it occurs. Your friend will thank you when he or she is trying to reproduce and debug the regression. Click the “import” button next to the start profiling button to load a profile from disk, and hit “save” on an existing profile to export it.

    profileimport

    When can I use these features?

    All of these features and more are available in the Aurora release channel. In another 12 weeks, these features will roll over into Firefox stable.

    Have some feedback about devtools? Ping @FirefoxDevTools on Twitter, or swing by #devtools on irc.mozilla.org.

  7. Old tricks for new browsers – a talk at jQuery UK 2012

    Last Friday around 300 developers went to Oxford, England to attend jQuery UK and learn about all that is hot and new about their favourite JavaScript library. Imagine their surprise when I went on stage to tell them that a lot of what jQuery is used for these days doesn’t need it. If you want to learn more about the talk itself, there is a detailed report, slides and the audio recording available.

    The point I was making is that libraries like jQuery were first and foremost there to give us a level playing field as developers. We should not have to know the quirks of every browser and this is where using a library allows us to concentrate on the task at hand and not on how it will fail in 10 year old browsers.

    jQuery’s revolutionary new way of looking at web design was based on two main things: accessing the document via CSS selectors rather than the unwieldy DOM methods and chaining of JavaScript commands. jQuery then continued to make event handling and Ajax interactions easier and implemented the Easing equations to allow for slick and beautiful animations.

    However, this simplicity came with a prize: developers seem to forget a few very simple techniques that allow you to write very terse and simple to understand JavaScripts that don’t rely on jQuery. Amongst others, the most powerful ones are event delegation and assigning classes to parent elements and leave the main work to CSS.

    Event delegation

    Event Delegation means that instead of applying an event handler to each of the child elements in an element, you assign one handler to the parent element and let the browser do the rest for you. Events bubble up the DOM of a document and happen on the element you want to get and each of its parent elements. That way all you have to do is to compare with the target of the event to get the one you want to access. Say you have a to-do list in your document. All the HTML you need is:

    <ul id="todo">
      <li>Go round Mum's</li>
      <li>Get Liz back</li>
      <li>Sort life out!</li>
    </ul>

    In order to add event handlers to these list items, in jQuery beginners are tempted to do a $('#todo li').click(function(ev){...}); or – even worse – add a class to each list item and then access these. If you use event delegation all you need in JavaScript is:

    document.querySelector('#todo').addEventListener( 'click', 
      function( ev ) {
        var t = ev.target;
        if ( t.tagName === 'LI' ) {
          alert( t + t.innerHTML ); 
          ev.preventDefault();
        }
    }, false);

    Newer browsers have a querySelector and querySelectorAll method (see support here) that gives you access to DOM elements via CSS selectors – something we learned from jQuery. We use this here to access the to-do list. Then we apply an event listener for click to the list.

    We read out which element has been clicked with ev.target and compare its tagName to LI (this property is always uppercase). This means we will never execute the rest of the code when the user for example clicks on the list itself. We call preventDefault() to tell the browser not to do anything – we now take over.

    You can try this out in this fiddle or embedded below:

    JSFiddle demo.

    The benefits of event delegation is that you can now add new items without having to ever re-assign handlers. As the main click handler is on the list new items automatically will be added to the functionality. Try it out in this fiddle or embedded below:

    JSFiddle demo.

    Leaving styling and DOM traversal to CSS

    Another big use case of jQuery is to access a lot of elements at once and change their styling by manipulating their styles collection with the jQuery css() method. This is seemingly handy but is also annoying as you put styling information in your JavaScript. What if there is a rebranding later on? Where do people find the colours to change? It is a much simpler to add a class to the element in question and leave the rest to CSS. If you think about it, a lot of times we repeat the same CSS selectors in jQuery and the style document. Seems redundant.

    Adding and removing classes in the past was a bit of a nightmare. The way to do it was using the className property of a DOM element which contained a string. It was then up to you to find if a certain class name is in that string and to remove and add classes by adding to or using replace() on the string. Again, browsers learned from jQuery and now have a classList object (support here) that allows easy manipulation of CSS classes applied to elements. You have add(), remove(), toggle() and contains() to play with.

    This makes it dead easy to style a lot of elements and to single them out for different styling. Let’s say for example we have a content area and want to show one at a time. It is tempting to loop over the elements and do a lot of comparison, but all we really need is to assign classes and leave the rest to CSS. Say our content is a navigation pointing to articles. This works in all browsers:

    <header>
      <h1>Profit plans</h1>
    </header>
    <section id="content">
      <nav id="nav">
        <ul>
          <li><a href="#step1">Step 1: Collect Underpants</a></li>
          <li><a href="#step2">Step 2: ???</a></li>
          <li><a href="#step3">Step 3: Profit!</a></li>
        </ul>
      </nav>
      <article id="step1">
        <header><h1>Step 1: Collect Underpants</h1></header>
        <section>
          <p>
            Make sure Tweek doesn't expect anything, then steal underwear 
            and bring it to the mine.
          </p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
      <article id="step2">
        <header><h1>Step 2: ???</h1></header>
        <section>
          <p>WIP</p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
      <article id="step3">
        <header><h1>Step 3: Profit</h1></header>
        <section>
          <p>Yes, profit will come. Let's sing the underpants gnome song.</p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
    </section>

    Now in order to hide all the articles, all we do is assign a ‘js’ class to the body of the document and store the first link and first article in the content section in variables. We assign a class called ‘current’ to each of those.

    /* grab all the elements we need */
    var nav = document.querySelector( '#nav' ),
        content = document.querySelector( '#content' ),
     
    /* grab the first article and the first link */
        article = document.querySelector( '#content article' ),
        link = document.querySelector( '#nav a' );
     
    /* hide everything by applying a class called 'js' to the body */
    document.body.classList.add( 'js' );
     
    /* show the current article and link */ 
    article.classList.add( 'current' );
    link.classList.add( 'current' );

    Together with a simple CSS, this hides them all off screen:

    /* change content to be a content panel */
    .js #content {
      position: relative;
      overflow: hidden;
      min-height: 300px;
    }
     
    /* push all the articles up */
    .js #content article {
      position: absolute;
      top: -700px;
      left: 250px;
    }
    /* hide 'back to top' links */
    .js article footer {
      position: absolute;
      left: -20000px;
    }

    In this case we move the articles up. We also hide the “back to top” links as they are redundant when we hide and show the articles. To show and hide the articles all we need to do is assign a class called “current” to the one we want to show that overrides the original styling. In this case we move the article down again.

    /* keep the current article visible */
    .js #content article.current {
      top: 0;
    }

    In order to achieve that all we need to do is a simple event delegation on the navigation:

    /* event delegation for the navigation */
    nav.addEventListener( 'click', function( ev ) {
      var t = ev.target;
      if ( t.tagName === 'A' ) {
        /* remove old styles */
        link.classList.remove( 'current' );
        article.classList.remove( 'current' );
        /* get the new active link and article */
        link = t;
        article = document.querySelector( link.getAttribute( 'href' ) );
        /* show them by assigning the current class */
        link.classList.add( 'current' );
        article.classList.add( 'current' );
      }
    }, false);

    The simplicity here lies in the fact that the links already point to the elements with this IDs on them. So all we need to do is to read the href attribute of the link that was clicked.

    See the final result in this fiddle or embedded below.

    JSFiddle demo.

    Keeping the visuals in the CSS

    Mixed with CSS transitions or animations (support here), this can be made much smoother in a very simple way:

    .js #content article {
      position: absolute;
      top: -300px;
      left: 250px;
      -moz-transition: 1s;
      -webkit-transition: 1s;
      -ms-transition: 1s;
      -o-transition: 1s;
      transition: 1s;
    }

    The transition now simply goes smoothly in one second from the state without the ‘current’ class to the one with it. In our case, moving the article down. You can add more properties by editing the CSS – no need for more JavaScript. See the result in this fiddle or embedded below:

    JSFiddle demo.

    As we also toggle the current class on the link we can do more. It is simple to add visual extras like a “you are here” state by using CSS generated content with the :after selector (support here). That way you can add visual nice-to-haves without needing the generate HTML in JavaScript or resort to images.

    .js #nav a:hover:after, .js #nav a:focus:after, .js #nav a.current:after {
      content: '➭';
      position: absolute;
      right: 5px;
    }

    See the final result in this fiddle or embedded below:

    JSFiddle demo.

    The benefit of this technique is that we keep all the look and feel in CSS and make it much easier to maintain. And by using CSS transitions and animations you also leverage hardware acceleration.

    Give them a go, please?

    All of these things work across browsers we use these days and using polyfills can be made to work in old browsers, too. However, not everything is needed to be applied to old browsers. As web developers we should look ahead and not cater for outdated technology. If the things I showed above fall back to server-side solutions or page reloads in IE6, nobody is going to be the wiser. Let’s build escalator solutions – smooth when the tech works but still available as stairs when it doesn’t.

    Translations

  8. People of HTML5 – Divya Manian

    HTML5 needs spokespeople to work. There are a lot of people out there who took on this role, and here at Mozilla we thought it is a good idea to introduce some of them to you with a series of interviews and short videos. The format is simple – we send the experts 10 questions to answer and then do a quick video interview to let them introduce themselves and ask for more detail on some of their answers.

    Divya Manian Today we are featuring Divya Manian, Web Opener at Opera Software.

    Most likely you came across Divya because of her involvement in HTML5 readiness and HTML5 Boilerplate. She is available on Twitter as @divya and is very much involved in the CSS standards working group.

    As you will see in the interview, Divya is a very pragmatic person when it comes to web standards and has a big passion for educating developers instead of woo-ing them.

    The video interview

    You can see the video on any HTML5 enabled device here (courtesy of vid.ly).

    10 Questions for Divya Manian

    1) I feel that right now is a terribly exciting time to be a web developer. Would you agree? What gets you really excited about the new tech we have to play with?

    Definitely. These are exciting times for a web developer. You have new tools to work with almost every other week and what your page is capable of doing has expanded significantly from just delivering static content to enabling real-time media streaming and more. We also have very strong developer tools for each browser: Opera’s Dragonfly, Chrome’s Developer Tools, IE Developer tools in addition to the original trail blazer Firebug. So, it is simultaneously easier and harder to develop for the web.

    2) Back in the days we very much preached separation of concerns as the right way to build web products. HTML is for structure, CSS for look and feel and JavaScript for behaviour. It seems to me that with new technologies this strict separation is blurring a bit. We can generated content in CSS and animate and transform. Some HTML5 elements do nothing without JavaScript (canvas being the big example). Do you think we need to re-visit our best practices?

    Yes, the new features do definitely make you think harder about what you put where, but they do enable a similar separation still, except there are nuances to be aware of when you do the separation.

    For example, I would consider animation with JavaScript as a way around the roadblock of not being able to do natively. Browsers are in a better position to control most of the animations that we require (animations for gaming are slightly different ballgame), and doing them natively would get us better performance in the long run.

    Personally, for me maintainability and writing something readable and that works well and efficiently is more important than just being driven to compartmentalise your code into HTML/CSS/JS.

    And definitely we do need to revisit our best practices every so often because technologies change and our best practices need to change with them, none of them are enshrined in stone and we should keep them relevant to our current set of features/technologies.

    3) In your post “This revolution needs new revolutionaries” you point out that a lot of the people who drive the web today are not the known luminaries of web design. Do you see a complacency in our advocacy of web standards?

    There are two concerns for me in that post:

    1. we are not hearing enough from people who have to deal with creating web applications that work in areas with poor internet connections, censorship, with content in languages that are not popular.

    2. There are not enough do-ers who are talking, we are hearing from the same people again and again on similar topics.

    I feel strongly about both, but more so about #2 because it impacts every web developer all over the world. There are changes that are occurring that most of them are unaware of, because word does not get out. I think we should do our best to encourage those who do actively seek to create tools, and help fellow web developers or work on interesting challenges for the web to speak and inspire rather than those who are known for their speaking abilities because ultimately we want people to use/work with what is best for the web and not just be informed of what was news 5 years ago.

    4) I found lately that collaboration is getting easier and easier. Tools like github, JSBin and JSFiddle allow you to talk about code and get your readers to fix and change things with you. I did that lately with getting bullet proof 90 degrees turned headlines for example. Why do you think not that many take advantage of that opportunity?

    I would be hesitant to say not many are taking advantage of these tools. They are, but it is true that not everyone is on the bandwagon yet. Github is certainly the most gentle and social introduction to version control you can get, but a lot of web developers are not programmers and have not seen enough pain and horror to know why version control systems are useful. It also requires knowing about what version control systems are, and how to use the command line (a bit), which might be scary for those who are just used to designing with IDEs or TextMate.

    5) CSS seems to be moving in leaps and bounds right now. I for one am very excited about the CSS element property which allows to take screenshots of elements. Are there any lesser known extensions you are fond of and use?

    I am not a big fan of vendor prefixes, and would rather see them quickly unprefixed rather than see more of the prefixes populating stylesheets more and more.

    That said, I do like a lot of the new properties that we are experimenting with. We have the obscure tab-size which allows you to control the width of the ‘tab’ character in your content. Pretty useful when you are displaying code.

    Opera also introduced the @viewport which will let you set the viewport from within your CSS rather than using meta tags (like <meta name=”viewport” content=”width=320″>). I think viewport belongs to CSS rather than markup, so I would love to see it gain adoption.

    Some of the less known properties such as box-sizing (unprefixed in Opera, IE 8+, Safari 5.1+, Chrome, prefixed in Firefox) are also invaluable, as they let you control your box model, which is definitely a revolutionary step from the dark days of trying to work with separate box models.

    6) When we had a longer chat before this interview we discussed that there seems to be a disconnect between what people show on stage at conferences and what people can use these days in their day-to-day jobs. Do you think we should remedy this? More hands-on stuff for people to use now rather than a “look what is possible” approach?

    I think what gets shown on stage is partly entertainment and partly information. I think it is hard to show “real hands-on” stuff without diving deep into it and losing half the audience while doing so. We need a balance for sure.

    7) When writing CSS these days I get very annoyed about having to repeat a lot of code with different browser prefixes. Animations are the worst with all keyframes having to be repeated. Do you use any preprocessors like SASS or LESS? What do you think of that approach?

    Yes, I was/am an early fan of Sass. I have been using it for 2.5 years (a lot less now as I do not deal with as much CSS as I would like to). I certainly think Sass/LESS would be the way to go forward for any web developer right now. They make CSS a lot more powerful and attempt to bring in programming paradigms that CSS sorely lacks. Attempts are being made by Tab Atkins at Google to bring these in a form of a proposal to the CSS WG, and hopefully we should see some form of support in the browser.

    I would definitely recommend doing it on the server side though, doing JIT compiling of such code would be such a disaster for performance.
    Especially today with so many vendor-prefixed extensions, not using such preprocessors would only cause more harm than not.

    8) You work for Opera, the browser that did implement the most of the HTML5 form elements. Why do you think others are reluctant to do the same? Do you think HTML5 forms are ready for prime time yet?

    It is certainly not true that others are reluctant. Chrome is pretty close to Opera in terms of support, and Firefox and IE10 are have various levels of support too. Yes, HTML5 forms need to be used with polyfills as of the moment, but I cannot wait for full support to land on all browsers so we can get beyond validating forms on the server.

    9) I get a feeling that there is a general fatigue of semantic matters in the HTML5 world. Showcases have no HTML at all or meaningless elements like DIVs as buttons and so on. Is it just not sexy enough when we can rotate things in 3D and make sounds?

    I am tired of semantics, too, really :) I think there is more to HTML5 than discussing when to use a section or a div or an article or an aside. Semantics are good to know about and learn to use, but we have had 15 years of talk about semantics surely we can go beyond that and learn about all the new stuff that occurs in HTML5 that will allow faster/more performant way to provide better experiences for your users.

    10) If you have a friend who just wants to start with web development, what would you tell them to do and go to? What is the most efficient way to get people hit the ground running these days?

    I would ask them to first hit the Opera Web Curriculum which has now moved to W3C – it is a wiki now so everyone is welcome to contribute to keep it up-to-date and relevant. Then I would highly recommend they refer to explanations and tutorials at the Mozilla Developer Center!

    Photo by Chris Casciano

    Do you know anyone I should interview for “People of HTML5″? Tell me on Twitter: @codepo8

  9. Firefox OS for developers – the platform HTML5 deserves

    Over the next few weeks we will publish a series of short videos here that explain what Firefox OS means for developers and how you can be part of the revolution it brings to the world.

    be-the-future

    In various conversations we’ve repeatedly heard from developers that they view Firefox OS as simply a third player in the mobile space next to Android and iOS. This is not exactly what we are trying to achieve. Firefox OS is unique in its approach as it doesn’t target the high-end markets already saturated by other platforms. Instead its goal is to replace feature phones in markets that have no access to high-end smartphones or aren’t even considered in closed application mechanisms like marketplaces. Furthermore we wanted to create the first truly open and web-standards based ecosystem and mobile operating system – nothing in Firefox OS is closed or alien to the Web.

    This is why we recorded this video series to explain in a short and simple fashion where you can go to get started as a developer for Firefox OS and how this means writing HTML5 without the limitations other platforms have in place for web-standards based applications.

    Today we start with a short video featuring Chris Heilmann (@codepo8) from Mozilla and Daniel Appelquist (@torgo) from Telefónica Digital/ W3C talking about the goals of Firefox OS. You can watch the video here.

    Resources mentioned in the video are:

    We hope you enjoy this and that it answers a few of the questions you had about Firefox OS. Watch this space for more videos in this series.

  10. ECMAScript 5 strict mode in Firefox 4

    Editor’s note: This article is posted by Chris Heilmann but authored by Jeff Walden – credit where credit is due.

    Developers in the Mozilla community have made major improvements to the JavaScript engine in Firefox 4. We have devoted much effort to improving performance, but we’ve also worked on new features. We have particularly focused on ECMAScript 5, the latest update to the standard underlying JavaScript.

    Strict mode is arguably the most interesting new feature in ECMAScript 5. It’s a way to opt in to a restricted variant of JavaScript. Strict mode isn’t just a subset: it intentionally has different semantics from normal code. Browsers not supporting strict mode will run strict mode code with different behavior from browsers that do, so don’t rely on strict mode without feature-testing for support for the relevant aspects of strict mode.

    Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally. Strict mode blazes a path to future ECMAScript editions where new code with a particular <script type="..."> will likely automatically be executed in strict mode.

    What does strict mode do? First, it eliminates some JavaScript pitfalls that didn’t cause errors by changing them to produce errors. Second, it fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that’s not strict mode. Firefox 4 generally hasn’t optimized strict mode yet, but subsequent versions will. Third, it prohibits some syntax likely to be defined in future versions of ECMAScript.

    Invoking strict mode

    Strict mode applies to entire scripts or to individual functions. It doesn’t apply to block statements enclosed in {} braces; attempting to apply it to such contexts does nothing. eval code, event handler attributes, strings passed to setTimeout, and the like are entire scripts, and invoking strict mode in them works as expected.

    Strict mode for scripts

    To invoke strict mode for an entire script, put the exact statement "use strict"; (or 'use strict';) before any other statements.

    // Whole-script strict mode syntax
    "use strict";
    var v = "Hi!  I'm a strict mode script!";

    This syntax has a trap that has already bitten a major site: it isn’t possible to blindly concatenate non-conflicting scripts. Consider concatenating a strict mode script with a non-strict mode script: the entire concatenation looks strict! The inverse is also true: non-strict plus strict looks non-strict. Concatenation of strict mode scripts with each other is fine, and concatenation of non-strict mode scripts is fine. Only crossing the streams by concatenating strict and non-strict scripts is problematic.

    Strict mode for functions

    Likewise, to invoke strict mode for a function, put the exact statement "use strict"; (or 'use strict';) in the function’s body before any other statements.

    function strict()
    {
      // Function-level strict mode syntax
      'use strict';
      function nested() { return "And so am I!"; }
      return "Hi!  I'm a strict mode function!  " + nested();
    }
    function notStrict() { return "I'm not strict."; }

    Changes in strict mode

    Strict mode changes both syntax and runtime behavior. Changes generally fall into these categories:

    • Converting mistakes into errors (as syntax errors or at runtime)
    • Simplifying how the particular variable for a given use of a name is computed
    • Simplifying eval and arguments
    • Making it easier to write “secure” JavaScript
    • Anticipating future ECMAScript evolution

    Converting mistakes into errors

    Strict mode changes some previously-accepted mistakes into errors. JavaScript was designed to be easy for novice developers, and sometimes it gives operations which should be errors non-error semantics. Sometimes this fixes the immediate problem, but sometimes this creates worse problems in the future. Strict mode treats these mistakes as errors so that they’re discovered and promptly fixed.

    First, strict mode makes it impossible to accidentally create global variables. In normal JavaScript, mistyping a variable in an assignment creates a new property on the global object and continues to “work” (although future failure is possible: likely, in modern JavaScript). Assignments which would accidentally create global variables instead throw errors in strict mode:

    "use strict";
    mistypedVaraible = 17; // throws a ReferenceError

    Second, strict mode makes assignments which would otherwise silently fail throw an exception. For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception. Any assignment that silently fails in normal code will throw errors in strict mode:

    "use strict";
    NaN = 42; // throws a TypeError
    var obj = { get x() { return 17; } };
    obj.x = 5; // throws a TypeError
    var fixed = {};
    Object.preventExtensions(fixed);
    fixed.newProp = "ohai"; // throws a TypeError

    Third, if you attempt to delete undeletable properties, strict mode throws errors (where before the attempt would simply have no effect):

    "use strict";
    delete Object.prototype; // throws a TypeError

    Fourth, strict mode requires that all properties named in an object literal be unique. Normal code may duplicate property names, with the last one determining the property’s value. But since only the last one does anything, the duplication is simply a vector for bugs, if the code is modified to change the property value other than by changing the last instance. Duplicate property names are a syntax error in strict mode:

    "use strict";
    var o = { p: 1, p: 2 }; // !!! syntax error

    Fifth, strict mode requires that function argument names be unique. In normal code the last duplicated argument hides previous identically-named arguments. Those previous arguments remain available through arguments[i], so they’re not completely inaccessible. Still, this hiding makes little sense and is probably undesirable (it might hide a typo, for example), so in strict mode duplicate argument names are a syntax error:

    function sum(a, a, c) // !!! syntax error
    {
      "use strict";
      return a + b + c; // wrong if this code ran
    }

    Sixth, strict mode forbids octal syntax. Octal syntax isn’t part of ECMAScript, but it’s supported in all browsers by prefixing the octal number with a zero: 0644 === 420 and "\\045" === "%". Novice developers sometimes believe a leading zero prefix has no semantic meaning, so they use it as an alignment device — but this changes the number’s meaning! Octal syntax is rarely useful and can be mistakenly used, so strict mode makes octal a syntax error:

    "use strict";
    var sum = 015 + // !!! syntax error
              197 +
              142;

    Simplifying variable uses

    Strict mode simplifies how variable uses map to particular variable definitions in the code. Many compiler optimizations rely on the ability to say that this variable is stored in this location: this is critical to fully optimizing JavaScript code. JavaScript sometimes makes this basic mapping of name to variable definition in the code impossible to perform except at runtime. Strict mode removes most cases where this happens, so the compiler can better optimize strict mode code.

    First, strict mode prohibits with. The problem with with is that any name in it might map either to a property of the object passed to it, or to a variable in surrounding code, at runtime: it’s impossible to know which beforehand. Strict mode makes with a syntax error, so there’s no chance for a name in a with to refer to an unknown location at runtime:

    "use strict";
    var x = 17;
    with (obj) // !!! syntax error
    {
      // If this weren't strict mode, would this be var x, or
      // would it instead be obj.x?  It's impossible in general
      // to say without running the code, so the name can't be
      // optimized.
      x;
    }

    The simple alternative of assigning the object to a variable, then accessing the corresponding property on that variable, stands ready to replace with.

    Second, eval of strict mode code does not introduce new variables into the surrounding code. In normal code eval("var x;") introduces a variable x into the surrounding function or the global scope. This means that, in general, in a function containing a call to eval, every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that eval might have introduced a new variable that would hide the outer variable). In strict mode eval creates variables only for the code being evaluated, so eval can’t affect whether a name refers to an outer variable or some local variable:

    var x = 17;
    var evalX = eval("'use strict'; var x = 42; x");
    assert(x === 17);
    assert(evalX === 42);

    Relatedly, if the function eval is invoked by an expression of the form eval(...) in strict mode code, the code will be evaluated as strict mode code. The code may explicitly invoke strict mode, but it’s unnecessary to do so.

    function strict1(str)
    {
      "use strict";
      return eval(str); // str will be treated as strict mode code
    }
    function strict2(f, str)
    {
      "use strict";
      return f(str); // not eval(...): str is strict iff it invokes strict mode
    }
    function nonstrict(str)
    {
      return eval(str); // str is strict iff it invokes strict mode
    }
    strict1("'Strict mode code!'");
    strict1("'use strict'; 'Strict mode code!'");
    strict2(eval, "'Non-strict code.'");
    strict2(eval, "'use strict'; 'Strict mode code!'");
    nonstrict("'Non-strict code.'");
    nonstrict("'use strict'; 'Strict mode code!'");

    Third, strict mode forbids deleting plain names. Thus names in strict mode eval code behave identically to names in strict mode code not being evaluated as the result of eval. Using delete name in strict mode is a syntax error:

    "use strict";
    eval("var x; delete x;"); // !!! syntax error

    Making eval and arguments simpler

    Strict mode makes arguments and eval less bizarrely magical. Both involve a considerable amount of magical behavior in normal code: eval to add or remove bindings and to change binding values, and arguments by its indexed properties aliasing named arguments. Strict mode makes great strides toward treating eval and arguments as keywords, although full fixes will not come until a future edition of ECMAScript.

    First, the names eval and arguments can’t be bound or assigned in language syntax. All these attempts to do so are syntax errors:

    "use strict";
    eval = 17;
    arguments++;
    ++eval;
    var obj = { set p(arguments) { } };
    var eval;
    try { } catch (arguments) { }
    function x(eval) { }
    function arguments() { }
    var y = function eval() { };
    var f = new Function("arguments", "'use strict'; return 17;");

    Second, strict mode code doesn’t alias properties of arguments objects created within it. In normal code within a function whose first argument is arg, setting arg also sets arguments[0], and vice versa (unless no arguments were provided or arguments[0] is deleted). For strict mode functions, arguments objects store the original arguments when the function was invoked. The value of arguments[i] does not track the value of the corresponding named argument, nor does a named argument track the value in the corresponding arguments[i].

    function f(a)
    {
      "use strict";
      a = 42;
      return [a, arguments[0]];
    }
    var pair = f(17);
    assert(pair[0] === 42);
    assert(pair[1] === 17);

    Third, arguments.callee is no longer supported. In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. For strict mode functions, arguments.callee is a non-deletable property which throws an error when set or retrieved:

    "use strict";
    var f = function() { return arguments.callee; };
    f(); // throws a TypeError

    “Securing” JavaScript

    Strict mode makes it easier to write “secure” JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website on behalf of other users. JavaScript in browsers can access the user’s private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript’s flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.

    First, the value passed as this to a function in strict mode isn’t boxed into an object. For a normal function, this is always an object: the provided object if called with an object-valued this; the value, boxed, if called with a Boolean, string, or number this; or the global object if called with an undefined or null this. (Use call, apply, or bind to specify a particular this.) Automatic boxing is a performance cost, but exposing the global object in browsers is a security hazard, because the global object provides access to functionality “secure” JavaScript environments must invariably. Thus for a strict mode function, the specified this is used unchanged:

    "use strict";
    function fun() { return this; }
    assert(fun() === undefined);
    assert(fun.call(2) === 2);
    assert(fun.apply(null) === null);
    assert(fun.call(undefined) === undefined);
    assert(fun.bind(true)() === true);

    (Tangentially, built-in methods also now won’t box this if it is null or undefined. [This change is independent of strict mode but is motivated by the same concern about exposing the global object.] Historically, passing null or undefined to a built-in method like Array.prototype.sort() would act as if the global object had been specified. Now passing either value as this to most built-in methods throws a TypeError. Booleans, numbers, and strings are still boxed by these methods: it’s only when these methods would otherwise act on the global object that they’ve been changed.)

    Second, in strict mode it’s no longer possible to “walk” the JavaScript stack via commonly-implemented extensions to ECMAScript. In normal code with these extensions, when a function fun is in the middle of being called, fun.caller is the function that most recently called fun, and fun.arguments is the arguments for that invocation of fun. Both extensions are problematic for “secure” JavaScript, because they allow “secured” code to access “privileged” functions and their (potentially unsecured) arguments. If fun is in strict mode, both fun.caller and fun.arguments are non-deletable properties which throw an error when set or retrieved:

    function restricted()
    {
      "use strict";
      restricted.caller;    // throws a TypeError
      restricted.arguments; // throws a TypeError
    }
    function privilegedInvoker()
    {
      return restricted();
    }
    privilegedInvoker();

    Third, arguments for strict mode functions no longer provide access to the corresponding function call’s variables. In some old ECMAScript implementations arguments.caller was an object whose properties aliased variables in that function. This is a security hazard because it breaks the ability to hide privileged values via function abstraction; it also precludes most optimizations. For these reasons no recent browsers implement it. Yet because of its historical functionality, arguments.caller for a strict mode function is also a non-deletable property which throws an error when set or retrieved:

    "use strict";
    function fun(a, b)
    {
      "use strict";
      var v = 12;
      return arguments.caller; // throws a TypeError
    }
    fun(1, 2); // doesn't expose v (or a or b)

    Paving the way for future ECMAScript versions

    Future ECMAScript versions will likely introduce new syntax, and strict mode in ECMAScript 5 applies some restrictions to ease the transition. It will be easier to make some changes if the foundations of those changes are prohibited in strict mode.

    First, in strict mode a short list of identifiers become reserved keywords. These words are implements, interface, let, package, private, protected, public, static, and yield. In strict mode, then, you can’t name or use variables or arguments with these names. A Mozilla-specific caveat: if your code is JavaScript 1.7 or greater (you’re chrome code, or you’ve used the right <script type="">) and is strict mode code, let and yield have the functionality they’ve had since those keywords were first introduced. But strict mode code on the web, loaded with <script src=""> or <script>...</script>, won’t be able to use let/yield as identifiers.

    Second, strict mode prohibits function statements not at the top level of a script or function. In normal code in browsers, function statements are permitted “everywhere”. This is not part of ES5! It’s an extension with incompatible semantics in different browsers. Future ECMAScript editions hope to specify new semantics for function statements not at the top level of a script or function. Prohibiting such function statements in strict mode “clears the deck” for specification in a future ECMAScript release:

    "use strict";
    if (true)
    {
      function f() { } // !!! syntax error
      f();
    }
    for (var i = 0; i &lt; 5; i++)
    {
      function f2() { } // !!! syntax error
      f2();
    }
    function baz() // kosher
    {
      function eit() { } // also kosher
    }

    This prohibition isn’t strict mode proper, because such function statements are an extension. But it is the recommendation of the ECMAScript committee, and browsers will implement it.

    Strict mode in browsers

    Firefox 4 is the first browser to fully implement strict mode. The Nitro engine found in many WebKit browsers isn’t far behind with nearly-complete strict mode support. Chrome has also started to implement strict mode. Internet Explorer and Opera haven’t started to implement strict mode; feel free to send those browser makers feedback requesting strict mode support.

    Browsers don’t reliably implement strict mode, so don’t blindly depend on it. Strict mode changes semantics. Relying on those changes will cause mistakes and errors in browsers which don’t implement strict mode. Exercise caution in using strict mode, and back up reliance on strict mode with feature tests that check whether relevant features of strict mode are implemented.

    To test out strict mode, download a Firefox nightly and start playing. Also consider its restrictions when writing new code and when updating existing code. (To be absolutely safe, however, it’s probably best to wait to use it in production until it’s shipped in browsers.)