Search Logger
Category: Microsoft News

Microsoft News

Exploring IE9’s Enhanced DOM Capabilities

5:25 pm - September 2, 2010 in IEBlog

For IE9 Platform Preview 4, we significantly re-architected how the Chakra JavaScript engine integrates into IE. This re-architecture, described in Dean’s post, subtly changes the programming model of the DOM for IE9 standards mode, making it consistent with new ECMAScript 5 capabilities, more interoperable with other browsers and aligned with emerging standards (WebIDL).

In this post I want to dive into the details of some of these programming model changes. You can take advantage of these enhanced DOM capabilities in the latest platform preview build. To highlight these changes, I’ll reference the Enhanced DOM Capabilities demo page that we released with the fourth Platform Preview.

All 24 puzzle pieces assembled into the image of the IE logo. This is a screenshot of IE9 running the Enhanced DOM capabilities demo at the IE Test Drive web page: http://ie.microsoft.com/testdrive/

That demo tests 24 capabilities that span 4 general categories:

  • DOM object inheritance from native JavaScript objects
  • JavaScript functional harmony with DOM objects
  • Interoperable programming features
  • New ECMAScript 5 support applied to DOM objects

The first two are closely related, so I’ll discuss them together:

DOM object inheritance from native JavaScript objects and JavaScript functional harmony with DOM objects.

Prior to IE9, the JavaScript engine was connected to the DOM via classic COM bindings. These legacy bindings allowed for only primitive object and function representations of the DOM to the JavaScript engine. Consequently, many basic JavaScript features that developers expected to be available to all objects and functions (including DOM objects like Window, Document, NodeList, etc.) were only available to native JavaScript objects (Array, Number, etc.).

The ECMAScript standard specifies basic operations that should work uniformly on all JavaScript objects, but allows “host objects” to deviate from those standard specifications. IE’s old JavaScript engine treated DOM objects as “host objects” which meant that basic JavaScript operations such as property access could behave oddly. While allowed by ECMAScript, inconsistent behavior between DOM objects and JavaScript objects created differences web developers had to account for.

For example, one common puzzler for many web developers was why IE DOM functions were reported as “object” to the typeof JavaScript operator rather than "function" (this capability is specifically checked in the demo as piece #10).

In IE9’s Standards Mode, we build our DOM as native JavaScript objects and functions rather than as “host objects,” thus enabling the features that web developers expect from native objects.

Interoperable programming features

The third group of capabilities showcase unique IE programming model behaviors that web developers commonly stumbled over. Because these behaviors were unique to the IE programming model, web developers found that their code didn't work the same across different browsers.

As part of our new integration architecture, we removed many of the inconsistencies that kept the same script from working the same way across browsers. The programming model changes may cause sites that have conditional code written for IE to behave differently in IE9 than it did before. Therefore, it is worthwhile describing these changes in more depth.

Functions now enumerated

In IE8 and before, enumerating a DOM object did not include any of that DOM object’s member functions. IE9 now enumerates any property on a DOM object that has its “enumerable” property descriptor value set to ‘true’. (In other words, enumeration can be programmatically altered.) Functions are now enumerated by default to be consistent with other browsers.

Removed implicit function invocation

DOM functions in previous versions of IE were quite special. Not only did they claim to be typeof “object”, but they also retained a static ‘this’ value which referred to the object to which they belonged. Consequently, it was possible to cache a reference to a DOM function, and invoke it without explicitly passing the ‘this’ value:

// Works in IE8 and earlier versions
// Doesn't work in IE9 or other browsers

var cachedGetElementById = document.getElementById;
cachedGetElementById('value');

In IE9, this now throws an exception, as it does in other browsers. Code that formerly depended on this IE behavior may use the “.call” workaround:

// Works in IE8/IE9 and other browsers
// Doesn't work in IE7 and earlier versions;

var cachedGetElementById = document.getElementById;
cachedGetElementById.call(document, 'value');

ECMAScript 5 provides a “bind” method for functions which allows them to take on the programming characteristics formerly supported by IE:

// Works natively in IE9 because of ECMAScript 5's 'bind' API
var cachedGetElementById = document.getElementById.bind(document);
cachedGetElementById('value');

Support for DOM exceptions and ‘const’ properties

The IE9 enhanced DOM now includes W3C-specified DOM exception objects and standardized error codes that web developers can use to determine (generally) the nature of a DOM API failure. These codes are commonly compared against well-defined 'const' properties to aid in code readability:


catch(ex) {
   if (ex.code == DOMException.INDEX_SIZE_ERR)
      …
}

The enhanced DOM provides the pre-defined 'const' properties as well as the architecture to throw and catch DOM exceptions.

Consistent toString behavior

With Chakra and the DOM fully integrated, the DOM does not have its own implementation of toString (a function that converts any object into a string form). While the old DOM’s toString implementation was similar to the JavaScript built-in version, it was not the same and often returned inconsistent or puzzling results. IE9 DOM objects now inherit and use the JavaScript built-in toString for more uniform results.

Separation of property and attribute storage

In the previous architecture, DOM objects had their own property storage. This property storage was the same as the storage location for attributes (those found in the HTML markup). With IE9's new architecture, an element’s attribute storage is now separate from the dynamic properties assigned to an element's script object. To illustrate this separation, consider the following example markup:

<div id="myId" class="c" user-defined-attribute="test">

In the above example, “id”, “class”, and “user-defined-attribute” are attributes. The div element's JavaScript object also exposes similar properties:

// Get the JavaScript object representing the body
var divOb = document.getElementById(‘myId’);
divOb.id;        // "myId"
divOb.className; // "c"

These JavaScript properties retrieve the values stored in an element’s attribute list. For example, “id” retrieves the value of the “id” attribute. “className” retrieves the value of the “class” attribute.

In previous versions of IE, any dynamically-added properties would “magically” appear in the element’s attribute list and vice-versa due to the shared storage location. This could lead to unexpected results:

<div id="myId" class="c" user-defined-attribute="test">

var divOb = document.getElementById("myId");
// The next statement unexpectedly adds "userProperty" as
// an attribute to the element.

divOb.userProperty = "test"

// How many attributes?
alert("Total attributes = " + divOb.attributes.length);

IE9 and other browsers alert three total attributes ("id", "class", and "user-defined-attribute"), whereas previous versions of IE alert 4, adding "userProperty" to the list. The reverse example is more common—code that expects user-defined attributes to appear as dynamic properties:

<div id="myId" class="c" user-defined-attribute="test" userAttribute="test">

var divOb = document.getElementById("myId");
// Get the "userAttribute" and "user-defined-attribute" value
// (only worked in IE8 and previous versions)
var value1 = divOb.userAttribute;
var value2 = divOb["user-defined-attribute"];

We’ve seen a lot of code that expects this legacy IE behavior. The interoperable way to retrieve unknown attributes is to use “getAttribute,”

var value1 = divOb.getAttribute("userAttribute");
var value2 = divOb.getAttribute("user-defined-attribute");

and dynamic properties should not be queried through the attributes collection.

New ECMAScript 5 capabilities

In the last group of capability tests, new functionality provided by Chakra’s implementation of ECMAScript 5 is applied to the DOM. One of the primary goals for the enhanced DOM in IE9 was to provide a representation of the DOM that made logical sense within the context of the ECMAScript 5 language semantics. This was made much easier because one of the primary goals of ECMAScript 5 is to better support the functionality needed by DOM objects! In our implementation, we represented the DOM using as many native ECMAScript 5 language features as possible, including extensive use of accessor (getter/setter) properties.

This native integration allows all of the new ECMAScript5 features to work equally well with native objects as with DOM objects.

The enhanced DOM capabilities demo shows only 24 samples of what is possible when the DOM is fully integrated with an ECMAScript 5-capable JavaScript engine like Chakra. We are very excited about this support in IE9 and want to help get better interoperability for ECMAScript language bindings across browsers. An important step is standardizing these binding within the W3C, and we’re happy to contribute to that effort.

W3C web standards have always supplied a language binding for ECMAScript implementations as a way to translate the standard IDL (Interface Definition Language) into JavaScript objects. However, these bindings lacked sufficient detail to create much more than a simple “host object” binding (a binding without consideration of the full spectrum of ECMAScript language features). While other browsers have a much more comprehensive language binding than simply “host objects,” integration inconsistencies remain. These inconsistencies can really frustrate JavaScript framework developers who wish to write abstraction layers and features on top of the basic language support. The need for consistency led to a proposed standard called WebIDL (Web Interface Definition Language). The WebIDL specification describes in much more precise detail, how to translate a given W3C spec written using WebIDL into JavaScript objects.

In a follow-up post, I will describe in more detail how we used WebIDL to inform and guide the development of the IE9 enhanced DOM.

Please testdrive the IE9 enhanced DOM. We look forward to your comments and feedback.

Travis Leithead
IE Program Manager

 

Add-on Performance part 2: Helping consumers make informed decisions

8:27 pm - August 31, 2010 in IEBlog

The platform previews show the focus in IE9 on performance, interoperable HTML5 through same markup, and hardware acceleration. We’ve also posted here about the work we’ve done with add-on developers, and we shared some data about add-on performance and how we measure it.

In this post, we cover more of our thinking about measuring add-on performance and how to help consumers to stay in control of their browsing experience.

Add-on Performance and Site Performance

We’ve written about the different dimensions of performance in the web platform. We have also talked about the role add-ons play in overall browser performance. Site developers want a reliable, fast platform to run their web sites. Consumers (site visitors) want a reliable, fast experience of those sites. The perception of site speed includes the user’s experience of the site, the browser, and the installed add-ons.

As discussed in Add-on Performance part 1, add-ons can have a material impact on site performance and the consumer experience. Our goal with IE is that users have everything they need to make informed decisions and remain in control of their browsing experience.

Measuring performance to inform decisions

It is important that people stay in control of their browsing experience. This includes many aspects of using the browser including downloads, privacy, security, and controlling which add-ons to use. The ideal experience allows people to have exactly the add-ons they want – no more no less.

For users, there is a basic cost to benefit decision to make with add-ons. To make an informed decision, the user needs to have a clear view on the costs of the add-on as well as the apparent benefits. Most people understand the benefit they get from using an add-on they choose to install. It is more difficult to understand the full cost that add-ons bring to your browsing experience in terms of performance, responsiveness, and reliability.

When we introduced Web Slices, Accelerators and updates to search providers in IE8 we started a pattern of making sure that people are in control of the add-on capabilities in their browser. These types of declarative add-ons do not have performance or reliability costs to the browsing experience. The main impact they have is taking up space in the favorites bar or right click menu. Sites can promote web slices or add-ons, and the user is in control to decide whether to add them or not. This is an important part of the add-on experience even for savvy users; namely that people must consent to have the add-on.

For the types of add-ons that do have a potential performance and reliability cost (toolbars and BHOs), the user needs additional information. IE8 users can see the load time for add-ons in the Manage add-ons dialog. This is a good start, but there is more IE can do to help people fully understand the impact an add-on has on browsing performance.

Ideally IE would measure both load time and the additional time it takes to navigate to sites (navigation time). Measuring this time for every navigation, including the first time the add-on runs, is crucial because it represents how long the user actually had to wait to load IE and navigate to their favorite sites on their PC.

An important part of informing users is providing a threshold to understand the impact of add-ons have on performance. No matter what hardware you’re running on - from low end netbooks which throttle the CPU for long battery life or high end gaming desktops – human perception thresholds don’t change. Several studies regarding website response time report that users notice any delay over 0.2 seconds. Actions that are faster than 0.2 seconds appear instantaneous.  Scenarios with response times slower than that threshold can feel “slow” to users. Of course, the individual person should be free to choose a different threshold that matches their particular browsing needs.

When considering the performance of add-ons, it is useful to do so in relationship to this threshold. People think about the speed of actions in the browser, like opening a new site, rather than the speed of individual add-ons, so what matters to the user is the total amount of time taken by add-ons. From the user’s point of view, they don’t care if it’s one add-on taking 2 seconds or 10 add-ons each taking 0.2 seconds. Informing users means providing the visibility on everything that is contributing to the performance they experience, with enough detail that the user stays in control. With this information people can make decisions about individual add-ons in the context of all the other add-ons that they’re running.

A personal decision

In part 1 of this series we shared statistical data about add-on performance which is compiled from people who opt into sending telemetry. Because this data is anonymous it’s useful for spotting broad trends and working with add-on partners but it’s not useful for helping a specific person in their environment. What matters to a person is what happens on his or her own machine. So, they need data that’s specifically about their add-ons on their machine with their browsing habits; purely local data. This enables them to make the most informed decision about the add-ons they use and to stay in control over their browsing experience

With this information, the user can make an informed choice. They understand the value of the add-on features and the performance implications. People may decide that an add-on is so valuable that they’re willing to wait a ¼ second or even a ½ second during their browsing. People may also decide that they don’t utilize the features of a particular add-on frequently so they disable it until they want it. Consistent with other browsers, IE makes re-enabling add-ons easy through the Manage add-ons dialog. The most popular entry point is in the right-click menu of the command bar but it can also be accessed from the tools menu, the right click menu for a page (under accelerators), the search box dropdown menu (under search providers), windows control panel and of course from the options dialog. Microsoft doesn’t share information with developers about individual users disabling or enabling add-ons in keeping with our privacy policy. Using add-ons is a personal choice, so IE never automatically enables or disables an add-on – the user is in control and they choose which to enable and which to disable. IE gives people the information they need to make an informed decision.

More details for add-on developers

For background, we’ve talked about using windows tools to measure load and navigation performance of add-ons. Here’s more detail about the load and navigation measurements so add-on developers can test the performance of their products or do something more like build capabilities into their products to detect when browsing is slowed and tune the add-on experience appropriately.

Add-on Load time (Load Time)

IE8 measures load time when a new tab is created and IE initializes all enabled add-ons (and IE9 will do this too). IE calls CoCreateInstance(), ShowDW() and SetSite() for each add-on. In IE8, an add-on’s load time is the total time it takes to return from the CoCreateInstance() and SetSite() calls. In the future, we’ll also measure the ShowDW() function call.

Webpage Navigation (Navigation Time)

Earlier in this post, we talked about the importance of measuring navigation time. Here’s how we do it on the IE team and how we recommend add-on developers do it. An add-on’s navigation time is the time it takes to handle the following three DWebBrowser2 events while navigating to a webpage:

  • BeforeNavigate
  • NavigateComplete
  • DocumentComplete

We start measuring a navigation time for all enabled add-ons once IE fires a top-level BeforeNavigate event.

Sites may cause several navigation events to fire as they download images or content in frames. So, we keep an open tally of the time the add-ons take for each event on that page until the user:

  • Navigates (another top-level BeforeNavigate)
  • Cancels the navigation
  • Closes the tab
  • Closes IE

Once that occurs, we append the navigation time data point for each of the add-ons to the list.

When showing the load or navigation time data to users, we average up to the last 10 data points. We don’t measure the performance of disabled add-ons since they aren’t running or taking any time to load or navigate. Instead we show the latest data we have in parenthesis to inform the enable decision for people.

In everything we do including add-on performance measurement, IE treats all add-ons from all developers the same. Only the user makes decisions to enable or disable add-ons.

Thanks,
Herman Ng

Edit on 8/31 - replaced ExtensionShowDW with ShowDW() and refer to it as a function call rather than an event in 'Add-on Load time (Load Time)' paragraph.  Also removed extra period.

 

Getting Ready for SVG Open

10:34 am - August 31, 2010 in IEBlog

I recently demonstrated Test Driving Modern SVG using the SVG Dice sample currently on the Internet Explorer 9 Test Drive site. While building this sample, I learned that both performance and interoperability for SVG are a subtle continuum and are not binary. This point resonated with me so much that I modified my presentation for this week’s SVG Open Conference entitled “The Future of SVG and HTML5” to include methods by which the SVG developer community can rally around to make SVG more interoperable.

Testing SVG vs. Test Driving SVG

SVG has its roots in a document format. The most popular use case today is the static document format. Complex engineering diagrams and other illustrations are well suited for SVG given their requirements for scalability, high fidelity printing, and portability.

With HTML5, the future of SVG is about the next generation of the interactive graphic web which exercises SVG in new ways. As a community, we need to think about how we test the SVG specification differently.

Testing SVG

The W3C SVG Test Suites attempt to “test” the ability to implement the spec, but as we learned in the working group, this is not enough to guarantee an interoperable set where a developer can use the same markup that works across all browsers. The SVG Test Suite is not intended to test conformance, but rather whether or not the spec can be implemented. From the W3C SVG Test Wiki:

“Our test suites are necessary, but not sufficient, to test conformance… Thus, representations of tested support is skewed toward the more complex features of SVG, and is not an accurate view of overall SVG support”

In other words, the existing test suite doesn’t test whether a browser conforms to the spec. To this end, we are working closely with the SVG Working Group to help round out these tests; in fact, there is an external effort to create an SVG DOM 1.1 conformance test by the SVG Interest Group. At the time of writing, IE9 passes 100% of these automated tests. In concert with the SVG Working Group, we are helping to resolve these interoperability issues by continuing to enhance the SVG Test Suite through regular contributions.

Additionally, there exists an imbalance between the number of requirements in the modules in the SVG Specification, and the number of tests in the SVG Test Suite that represent those requirements. The Internet Explorer team helps to address this imbalance through test asset contributions. But this is not enough. We have contributed 56 tests and expect to continue to deliver more over time.

Test Driving SVG

The better measure of conformance and more importantly interoperability was do develop more complex SVG for the web. My own experience in test driving SVG by developing the SVG Dice demo illustrates some of the places where we have more work to do as a community on interoperability of SVG.

The SVG specification contains over 2000 individual requirements. This is a large number in comparison to other web specifications and means that there is plenty of room for different interpretations. We strive in the SVG W3C Working Group to identify these differences. When I developed the SVG demo with the requirement that it works across browsers, my eyes were opened to some of the difficulties web developers face.

Most of the interoperability issues stem from a combination of the large number of requirements, the dependencies on other specifications, and the lack of significant content on the web to ensure the features are interpreted the same by both developer and browser vendors alike. SVG is relatively new ground for web developers and whereas HTML and CSS have enjoyed decades of refinement by a large scale of users, SVG has not yet had the same level of use and scrutiny.

Now that SVG is a part of HTML5, we expect to see traditional web developers learning new and better ways to improve experiences for their users using vector graphics. At the last SVG Face to Face meeting, the SVG Working Group assembled scenarios for SVG that provide for more targeted use cases for the next generation, graphical web. SVG plays an integral role here.

Comparing Implementations

I wrote the SVG Dice demo from my own understanding of the specification using Internet Explorer 9 and subsequently tested it in other browsers. In most cases where I ran into conflicting behavior, at least two browsers still agreed. Sometimes Internet Explorer’s behavior matched Chrome or Safari, and other times it matched Firefox or Opera. Because Internet Explorer is the most recent implementation, it benefits from an SVG Specification that is in last call where at least some of the ambiguities and conflicts have been resolved in the specification. Clearly there are more.

Something that caught me off guard was the impact of performance on my development effort.

From a developer’s perspective, I wanted to use the same graphic features like opacity, gradients, and masks in all browsers, in order to provide a consistent interoperable user experience, but I couldn’t do that because of performance concerns. Fully hardware accelerated graphics on Windows helps to move these graphic intensive computations to the GPU. I added the “Low Fidelity” mode to enable users to experience this demo in browsers that don’t make full use of the GPU. One nice side effect is that this also demonstrates CSS styling of SVG.

The Surprising “Switching Event”

Debugging the differences between browsers caused a very interesting “switching event” for me as a developer. There were a few outstanding bugs in the IE9 debugging tools (now fixed) which prevented me from placing breakpoints in code when working with SVG, so I used the popular Firebug add-on for Firefox. However, running the demo on Firefox was too slow, so I reverted back to Internet Explorer 9 to debug.

I eventually found work-arounds for most of the incompatibilities without having to write browser specific code, but it required far more effort than expected or considered reasonable.  We have more work to do here as a community in building the promise of same markup for SVG.

The Code

Because SVG is an older spec but new to a lot of developers, I thought I would review some of the code and concepts in this demo up close.

The Document Structure

As a first example, most browsers do not yet support SVG in HTML5.  I had to structure the document as XHTML with inline SVG.

<!DOCTYPE html>
<html id="demohtml" xmlns="http://www.w3.org/1999/xhtml" class="testdrive">
<head>
<title>
SVG Dice
</title>
</head>
<body id="demobody" onload="Setup()">
<audio id="sndRemove" volume="1" src="assets/remove.mp3" preload="true" ></audio>
<svg overflow="visible" id="theSVG" xmlns=http://www.w3.org/2000/svg
xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" >
</svg>
</body>
</html>


The above simple <!DOCTYPE html> sets Internet Explorer 9 to run in “standards mode” where SVG is supported. Notice that the SVG is embedded directly into the HTML. Both the css and the script are linked in via the HTML elements as expected.

<script type="text/javascript" src="demo.js"></script>
<link rel="Stylesheet" type="text/css" href="demo.css" />

At this point I have my basic html and svg document, stylesheet, script file structures. Next I need to build the graphical elements, provide the styles and write the script necessary for the animations and user experience.

Adding the Content

One of the great benefits and unique nature of the web development community is what we called the “copy/paste” use case. Any developer can readily search Wikimedia for public domain SVG art and use these directly in their applications or on their sites. Other popular tools exist for generating new or modifying existing content, from the open source Inkscape which focuses specifically on SVG, to other graphic tools from Microsoft and Adobe which export to SVG. I used existing open source clip art for the dice and for the boat.

Initially I had kept these SVG sources in different files for the purpose of separation. Unfortunately, I ran into several different issues across browsers from sizing to SVG Images support, which forced me to include all of the SVG in the one HTML file.

SVG contains the concept of <defs>, which is used to define an element(s) with styles and attributes, that can be re <use>d later. These two concepts are very powerful. They allow me to create many different sized dice for use as the image on the cup, those that fall into the cup, or those that roll across the screen during game play. I organized the <defs> from the various files at the top document immediately after the SVG tag.

<defs>
<!-- for left die -->
<linearGradient id="grad21" x1=".445" x2=".554" y1=".442" y2=".555">
<stop stop-opacity=".9" offset="0" stop-color="#470808"/>
<stop stop-opacity=".9" offset=".65" stop-color="#700d0d"/>
<stop stop-opacity=".9" offset="1" stop-color="#8c1111"/>
</linearGradient>
</defs>

These <defs> are later referenced:

<!-- edges -->
<path d="M 2474 4434 L 4860 2945 C 5009 " fill="url(#grad21)"/>

Once the <defs> were in place and the main clipart content was inline, I designed the rest of the experience, keeping in mind that SVG renders in layers from top to bottom. The majority of the remaining content was the scoreboard, the felt, the text and the cup.

Adding the User Interactivity and Animations

One of the more challenging aspects of this demo was organizing the sizing. One of the first things I do in the code is register the resize event, and set up the dimensions of the <svg> and the contained svg fragments. For simplicity, I <g>rouped them so I can apply scaling and positioning individually.

document.getElementById("theSVG").setAttribute("width", surfaceWidth.toString() + "px");

Something to take notice of immediately here is that this JavaScript code is familiar to web developers because it is standard JavaScript working with the DOM. SVG has its own DOM methods which I use, but I mostly stick to DOM Level 2 constructs as there is general agreement in the SVG Working Group that the SVG DOM might need revisiting.

Next I needed to take both of the static dice as SVG Fragments, and create some code to clone them, store references in an array with properties that allow me to manipulate their transforms for the animation effects, as well as ensure the physics engine recognizes them accordingly. The loop to create the dice is straightforward; it loops through the number of dice desired, clones the original into the DOM and creates an array to manage them.

Note: Most code samples here are trimmed for brevity, but all of the code is on the Platform Preview site http://ie.microsoft.com/testdrive/Performance/SVGDice/Default.xhtml)

First I clone the prototype and add it to the DOM, setting some default attributes along the way. Note the establishment of the transform is used to move the dice (translate), rotate the dice (rotate) and size the dice (scale).

// create an instance of die #1 and add it to the SVG Doc
this.die1 = createElement("g");
var tmpChild = this.die1.appendChild(createElement("g"));
var tmpNode = this.die1.appendChild(tmpChild);
tmpNode.appendChild(nodeDie1.cloneNode(true));
// set some default attributes
this.die1.setAttribute("id", "die_1_" + number.toString());
this.die1.setAttribute("transform",
"translate(" + this.x.toString() + "," + this.y.toString() + ")
scale ("
+ this.scale.toString() + ")");


I wanted to make use of the <use> element here as this is a great way to clone a group of SVG fragments. Unfortunately, the implementation of <use> varies across browsers, specifically in the case of styling and events.

Next I use the SVGDOM getBBox() method to grab the dimensions of the die as we shrink each one along the way. This method returns an SVGRect which is used in the physics engine to detect collision.

var rectSize = this.die1.getBBox(); // calculate dimensions for use with physics
this.height = rectSize.height;
this.width = rectSize.width;

One of my favorite parts of building this sample was the discovery and use of the Box2DJS engine which made physics a breeze! This engine is used in many projects and is now available to web developers. Before I create the dice, I actually initialize the world around me:

function createWorld(width, height) {
var worldAABB = new b2AABB();

var world = new b2World(worldAABB, gravity, doSleep);
createGround(world, width, height);
// Side
createBox(world, 0, 0, 30, height);
createBox(world, width, 0, 30, height);
createBox(world, 0, 0, width + 30, 30);
createBox(world, 0,height , width+30,30);

return world;
}

And then during dice creation I add each die to the world and give it an initial velocity.

// add this dice to the physics engine
this.circleBody = createBall(world, this.xTrans, this.yTrans, this.width);
// give the force a slightly random starting velocity
this.circleBody.SetLinearVelocity(initialForce);

After adding some user interaction to add dice, I remove dice and shake the cup. Then, I create a timer and step the world.

timer = window.setInterval(DoStuff, 16);
// move the world
world.Step(timeStep, iteration);

The Die class has a prototype update function that is called when the world steps. The primary mechanism for moving the dice is to get the coordinates from the physics engine and set the transform property with all of the elements originally established:

var transFormString = "translate(" + Math.round(this.circleBody.m_position.x)
+ "," + Math.round(this.circleBody.m_position.y) + ") scale (" +
this.scale.toString() + ") rotate(" + Math.round(this.rotation).toString()
+ "," + Math.round(this.xTrans).toString() + "," +
Math.round(this.yTrans).toString() + ")";

We now have moving, rolling, colliding dice.

Note that using the transform attribute is not necessarily the fastest approach, depending upon the implementation. As mentioned previously, I shied away from the SVGDOM which provides methods such as setTranslate() and setRotate(). The method I chose here considers potential future use of CSS Transforms with CSS Transitions and/or CSS Animations.

Styling the Graphics

Lastly, I wanted to take advantage of SVG integrated into the DOM and use CSS to change the style of the scene. Since the original art came from a design tool, it contained RGB values for colors and opacities.

<linearGradient id="cgrad2c" x1="1" x2=".17" y1="0" y2=".58">
<stop stop-opacity=".9" offset="0" stop-color="#700d0d"/>
<stop stop-opacity=".9" offset="1" stop-color="#b51616"/>
</linearGradient>

I replaced these RGB values with styles:

<linearGradient id="cgrad2c" x1="1" x2=".17" y1="0" y2=".58">
<stop class="diceCorner6"/>
<stop class="diceCorner7">
</linearGradient>

This allowed me to create style sheets for each of these styles:

g#classHandler.vegas .diceCorner6 {stop-opacity:.9;offset:0;stop-color:#700d0d;}
g#classHandler.vegas .diceCorner6 {stop-opacity:.9;offset:1;stop-color:#b51616;}

g#classHandler.lowfidielity .diceCorner6 {offset:0;stop-color:#000000;}
g#classHandler.lowfidielity .diceCorner6 {offset:1;stop-color:#000000;}

And then set the one class property at the top of the document to change all of the styles in the document:

// set the overall stylesheet via class
document.getElementById("classHandler").setAttribute("class", style);

This allows the user to change the style sheet even while the dice are rolling as there is no difference to the DOM as to when these styles are changed. Hardware accelerated graphics in Internet Explorer 9 enable this to happen very quickly.

Call to Action

Start working with SVG in Internet Explorer 9. IE9 is platform complete for SVG in the latest platform preview release. Experiment with the feature set and tell us about incompatibilities or bugs you find using the “Report Issue” command and on Microsoft Connect.

The IE team is testing sites, libraries and other SVG content on the web. Our goal is to help authors with their content and find any bugs in our feature set. One important best practice is using feature detection, not browser detection when testing for SVG support. Help us find the places where developers are detecting specific browsers instead of testing for functionality, and make any changes to open source libraries, or contact content authors such that we can help fix any issues that may arise.

We’re excited to see web developers start using this technology and the next generation, graphically rich, websites built with SVG.

Patrick Dengler
Senior Program Manager
Internet Explorer

 

Performance: Profiling how different web sites use browser subsystems

2:47 pm - August 30, 2010 in IEBlog

When we first showed IE9 at the Professional Developers Conference last fall, we discussed how real world browser performance involves many different subsystems. Different websites use these subsystems in different ways, and to build a fast real world browser you have to start by understanding these overall patterns. This post provides an inside look at how these subsystems impact the performance of five real world websites. We use Internet Explorer 8 for this analysis, and as IE9 approaches we’ll talk more about how these performance characteristics evolve.

All modern web browsers are conceptually similar. Browser vendors have different priorities (for example, supporting many different operating systems or optimizing for one). Browser vendors also have different engineering approaches which influence their programming languages, tools, and processes. When you step back from the specific engineering details though, all modern browsers connect to a server and execute the same markup and script. They all essentially do the same thing to enable customers to interact with web sites.

Browser Subsystems

The Internet Explorer web platform is composed of 11 core subsystems. All modern browsers provide these capabilities, and while the names and component boundaries vary slightly between browsers, the process is nearly identical.

Progression of IE subsystems.  Networking --> HTML --> CSS --> Collections --> Javascript --> Marshalling --> Native OM --> Formatting --> Block Building --> Layout --> Display

Here’s a brief overview of these subsystems in the order they’re encountered when you load a web site:

Networking: The first subsystem generally encountered is networking. The networking subsystem is responsible for all communication between the client and server, including local caching of web content. The networking subsystem is generally gated on the performance of the user’s network

HTML: As HTML documents are downloaded from the server they’re passed to an HTML subsystem which parses the document, initiates additional downloads in the networking subsystem, and creates a structural representation of the document. Modern browsers also contain related subsystems which are used for XHTML, XML and SVG documents.

CSS: When CSS is encountered, whether that’s inside an HTML document or a CSS document, it’s passed to a CSS subsystem which parses the style information and creates a structural representation that can be referenced later.

Collections: HTML documents often contain metadata, for example the information described in the document head or the attributes applied to an element. The collections subsystem is responsible for storing and accessing this metadata.

JavaScript: When script is encountered, it’s passed directly to the JavaScript subsystem which is responsible for executing that script. The JavaScript subsystem is probably the most well-known of the browser subsystems thanks to the visibility it has received over the last few years.

Marshaling: Because most JavaScript engines are not directly integrated into the browser, there is a communication layer between the browser and the script engine. Passing information through this communication layer is generally referred to as marshaling.

Native OM: JavaScript interacts with the document through the Document Object Model API’s. These API’s are generally provided through a subsystem which knows how to access and manipulate the document and is the primary interaction point between the script engine and the browser.

Formatting: Once the document is constructed, the browser needs to apply the style information before it can be displayed to the user. The formatting subsystem takes the HTML document and applies styles.

Block Building: CSS is a block based layout system. After the document is styled, the next step is to construct the rectangular blocks that will be displayed to the user. This process determines things like the size of the blocks and is tightly integrated with the next stage - layout.

Layout: Now that the browser has styled the content and constructed the blocks, it can go through the process of laying out the content. The layout subsystem is responsible for this algorithmically complex process.

Rendering: The final stage of the process occurs inside the rendering subsystem where the final content is displayed to the user. This process is often referred to as “drawing to the screen” and may occur on the CPU, the GPU, or a combination of both.

As we’ve mentioned, different websites use these subsystems in different ways. Even websites that provide similar functionality, for example some of the world’s largest news websites which provide comparable experiences on their home pages including headlines and video, have very different performance characteristics.

Profiling News Sites

To help you understand what we mean, we took five of the world’s largest news websites and profiled them loading inside IE8 using the Windows Performance Tools. We do this in a controlled environment to remove external variables and we load each site multiple times to ensure high confidence with the results. We factor out networking performance from these charts because that’s user dependent. This approach allows us to see how long it takes the browser to load the web site and the breakdown of CPU time across subsystems. In the below chart, you can see that it took between 1,117 and 3,704 milliseconds to load these five pages - that’s between 1.1 and 3.7 seconds. The color coding represents the browser subsystem where the time was spent.

Chart of subsystem Breakdownfor Common News Sites

There are some revealing patterns in these results. For example, News Site #1 spent the majority of the time in JavaScript, News Site #2 spent the majority of the time in Marshaling, and News Site #5 spent the majority of time in the Layout process which includes Formatting and Block Building. For each website a different subsystem made the largest impact on performance.

It’s also interesting to see how much control the web developer has over their own site’s performance. Even though News Site #3 provided a comparable experience to their competitors, they follow performance best practices and the site is quickly loaded in just over a second. In contrast, News Site #4 doesn’t follow many best practices and takes over three times as long to load.

When we average these results together we can start to understand the relative impact each subsystem has across news sites. As you see below, every subsystem plays an important role in the performance of these News Sites with JavaScript (29%), Marshalling (18%) and Rendering (17%) making the largest impact.

Chart of amount of time inside each browser subsystem on News Sites

Profiling Top AJAX Sites

News sites provide one view into how performance is multidimensional; however it’s important to look at other classes of web sites to see how these patterns change. When we perform the same analysis on the world’s top 25 AJAX sites, including some of the most sophisticated JavaScript applications like Facebook, Gmail and Hotmail, we get the following results.

Chart of Amount of time inside each browser subsystem on AJAX sites

As you can see the distribution has shifted slightly. Some subsystems including HTML, CSS and JavaScript become relatively less important and other subsystems including Formatting, Layout, Block Building and Rendering become extremely important. This can be surprising at first since most people associate AJAX sites with JavaScript. When you think about the patterns inside AJAX sites though, these results make sense. Inside most AJAX sites you generally have a small amount of JavaScript that manipulates the document. Once that script executes, the browser needs to go through almost all of the subsystems for that change to become visible to the user. That process is generally more expensive than executing the script itself.

You can see that performance of AJAX sites is also multi-dimensional and impacted by all of the subsystems in the browser. For AJAX sites, the most important subsystem is rendering which accounts for 31% of the time, followed by the JavaScript subsystem which accounts for 21% of the time. It’s interesting to see how JavaScript subsystem performance has proportionately more impact when loading a web page than when interacting with an AJAX site.

Bringing It All Together

To build a fast real world browser you have to understand how different browser subsystems impact performance in real world scenarios, and you have to focus on the subsystems that matter. For AJAX sites, that means focusing on Rendering (31%), JavaScript (21%), Formatting (14%) and Layout (12%). For news sites, that means focusing on JavaScript (29%), Marshalling (18%) and Rendering (17%).

With Internet Explorer 9, we worked on building the right foundation across the browser to ensure developers have a reliably fast platform. Over the last few months we’ve talked about some of the fundamental changes we made including hardware accelerated graphics, compiled JavaScript, and natively integrating JavaScript directly inside the browser. As we get closer to the IE9 beta we’ll talk more about how these subsystems come together in IE9 to change the performance characteristics compared to today’s generation of non-hardware accelerated browsers including IE8.

Jason Weber
Lead Program Manager, Internet Explorer Performance

 

More on SVG

5:00 pm - August 27, 2010 in IEBlog

The first IE9 Platform Preview unveiled IE9’s initial support of SVG. As explained previously, SVG is a vector image format managed by the W3C. The release of the third and fourth Platform Previews come with feature-complete SVG. Major additions include support for SVG gradients, patterns, clipping, and masking. These features are often used to create images with depth and texture and are typically found in more complex SVG files. Just like the rest of SVG in IE9, the newly added features are fully hardware accelerated. This results in impressive performance especially for computationally complex features such as clipping and masking. We continue to work with the SVG Working Group to resolve ambiguities in the SVG 1.1 2nd edition specification and to ensure that IE9’s SVG implementation is interoperable.

9 Things I <3 About SVG

SVG’s benefits are multifaceted. It’s an incredibly flexible and powerful format that is ideal for a variety of use cases. Here are just a few of the reasons why SVG can play a critical part of the HTML5 web:

1. Scale-ability

An obvious benefit of SVG is scalability, as evidenced by the name Scalable Vector Graphics. This makes it an ideal format for maps, charts, and graphs – graphics where the detail is as important as the overall picture. With SVG, the fidelity of the graphic is maintained at all resolutions. A company logo or website icon can be created once and used many times in different places or sizes. The same image no longer needs to be saved at multiple resolutions, each tailored towards a specific purpose. Maps often need to be viewed as a whole in addition to being able to selectively see sections in detail. Currently, a common format for maps is a PDF file. This format makes it easy to to scale the map to different sizes,print at many resolutions with full fidelity, and provides the user with the ability to search within the document. SVG has all of these positive qualities natively supported; no plugins are required. Preset views of the same document can even be defined to make navigation to different sections simpler.

2. Script-ability

SVG is supported by a rich DOM, making it easy to script and manipulate SVG with Javascript. Because SVG shapes are graphic objects akin to HTML elements, SVG scripting uses common patterns that web developers already understand. SVG elements can take event handlers; they can be modified via the DOM or by the DOM L2 Core setAttribute() and getAttribute() methods. All attributes that describe the SVG element can be modified, from position to color to the shape of the element. The example below demonstrates how event handling and scripting can be used to create interactive SVG.

Your browser or viewer does not support xhtml with svg, view this post in IE9 or another browser to use the examples. Get IE9 Platform Preview.

Script:

var colors = ["orange", "black", "yellow", "red", "blue", "fuchsia"];
var curColor = 0;

function alternateColor() {
	var circle = document.getElementById("myCircle");
	curColor = (curColor + 1) % colors.length;
	circle.setAttribute("fill", colors[curColor]);
	circle.setAttribute("stroke", colors[curColor]);
}

SVG:

<svg xmlns="http://www.w3.org/2000/svg" height="150" width="150">
	<circle onclick="alternateColor();"
		cx="75" cy="75" r="50"
		fill="orange"
		stroke="orange" stroke-opacity=".5" stroke-width="10"
		id="myCircle"/>
</svg>

3. Style-ability

There are several ways to include SVG on a webpage. The <embed>, <object>, <iframe>, <img> tags can reference an SVG file. SVG can be included via CSS as a background-image or a list-style-image. To really integrate SVG with the page, it can be included inline in XHTML or HTML5. Standalone SVG documents and inline SVG have the advantage of being fully incorporated in the webpage. The SVG is treated just like other HTML elements and is styled with the same CSS block that styles the entire page. Websites – complete with icons, logos, navigation UI, and other SVG graphics – are skinnable with stylesheets alone. A print stylesheet can even be applied to your SVG images to allow more control over the appearance of the image on paper. Take a look at the example below. If you’re using a browser that supports SVG, you can switch between stylesheets to see how SVG images can change just by altering a simple stylesheet!

4. Search-ability

SVG is a format based on XML, so it’s composed of elements and attributes that are human-readable. Text in an SVG file shows up as text in markup. The XML format enables users to search the document for text, which is not possible in the more traditionally popular GIF and PNG image formats. For developers, the text-based format means that text in SVG images is surfaced to search engines. With this information, a website can be more comprehensively indexed and found by the right people. For example, a flow chart can be picked up by a search engine without requiring the web author to transcribe every panel of the chart.

5. Accessibility

In addition to the searchable aspect of SVG, another benefit of the text-based format is accessibility. Unlike raster images which can have a single, all-encompassing title text and description, the <title> and <description> elements can be applied to any SVG element. A web author can provide a description for each individual component in addition to the whole document, providing a more detailed description  while making it easier to understand. An SVG document has structure to it, which can enable a clearer understanding of it. Additionally, the “focusable” attribute can be added to make it easy to tab through select portions of the SVG.

6. Decorative Text

SVG is not restricted for use on graphically intense websites. It can be used throughout an HTML5 or XHTML file. It’s a terrific option for decorative text headers. SVG text can be styled in more ways than HTML text. Gradients and patterns can be used in SVG text. SVG text can also be stroked, unlike HTML text. Compared to raster images, SVG text is much more flexible for editing. Used in combination with a CSS block, text across many areas of the document can be given the same appearance, much like HTML headers today. And with IE9’s support for WOFF, you can even apply the same WOFF font used elsewhere on your page! SVG text can be rotated or laid out along a custom path. Overall, SVG text enables more flexibility and creativity in text on a webpage. Try the example below to see how easy it is to create decorative text!

7. Data-Driven/Server-Generated SVG

SVG is an XML specification, making it a good target format for server-generated images. Server-generated XML is fairly common; RSS and Atom feeds are a couple of examples. Maps, charts, and graphs often draw from a store of data. SVG is already a prime candidate for these types of documents. With the ease of XML generation, SVG really shines as a fantastic format for creation of these informational images.

8. Seamless Browsing Experience

One of SVG’s advantages over alternative 3rd party plug-ins (such as Flash or Silverlight) is native browser support which offers several benefits. To experience SVG on the web, users don’t need to install add-ons. Built-in support is convenient for the user and reduces exposure to potential add-on vulnerabilities. SVG is hardware accelerated in IE9, offering a smoother interactive and viewing experience for users. Additionally, SVG offers better integration with page markup, DOM, and script to provide for a consistent programming model and better user experiences.

In IE9, SVG is treated much like an image today and matches user expectations of an image: it can be saved into the PNG and BMP raster image formats; it can be copied and pasted into a Word document or Powerpoint presentation as a rasterized version -- much like PNGs, JPEGs, and GIFs found on the web today; it can be set as a desktop background; printing SVG is just like printing an image. The browser also takes advantage of the benefits of SVG: it can be saved in the SVG format; it can be copied and pasted into Inkscape for editing as SVG; SVG text is searchable. Native support for SVG makes it easier for users to have a consistent browsing experience.

9. Familiarity/View Source

Because SVG is an extension of XML, learning SVG is merely an adaptation of XML/HTML knowledge that many developers are already familiar with. Many of us learned HTML using a browser’s View Source feature with Web sites we admired. SVG works the same way: View Source on a SVG file or an HTML5 file with inline SVG, and you can see, learn, and understand how an SVG graphic was made. And SVG elements work with IE9’s  debugging tools. As such, SVG is a web technology that is easy to pick up.

Additionally, several commonly used tools – such as Visio or Adobe Illustrator – are already capable of outputting SVG files. Inkscape is another fantastic tool for creating SVG; it specifically targets SVG as an output format and is free to download.  Using SVG on the web is a natural transition.

Call to Action

If you plan to use SVG on your website, you may also want to provide fallback behavior for browsers that do not support SVG. Depending on the context, it may be appropriate to use text, an image, or a combination of both to supplant the SVG. Remember to use feature detection, not browser detection to determine which format to display. SVG has an assortment of feature strings to describe SVG support for different modules. Using a try-catch statement and the hasFeature() method, you can determine if SVG is supported by the browser. For example:

try {
	if (document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Structure", "1.1")) {
		// display SVG
	}
	else {
		//fallback behavior
	}
}
catch(e) {
	// fallback behavior
}

Alternatively, if you embed SVG on your page as separate .SVG files, you can use the take advantage of the <object> tag by placing your fallback behavior within as follows:

<object data="vectorPanda.svg" type="image/svg+xml"><img src="pandaFallbackImage.png"></object>

If you are already serving SVG in HTML5 pages on your website, make sure that your HTML5 pages have the proper doctype so the pages load in the desired Document Mode. With no DocType present, IE9 will render in Quirks Mode and your beautiful SVG content will not display. Including the HTML5 DocType is as simple as inserting <!DOCTYPE html> as the first line of your Web page’s markup.

If you’re serving SVG within XHTML or directly as SVG, ensure that your Web server is serving with the proper MIME types:
                XHTML = application/xhtml+xml
                SVG = image/svg+xml

Please try SVG in the Platform Preview and see how it can enhance your site! Let us know what cool ideas you come up with. We’d love to see them!

Jennifer Yu
Program Manager

 

Chakra: Interoperability Means More Than Just Standards

7:31 pm - August 25, 2010 in IEBlog

How do we decide whether to implement a feature that isn’t included in a standards specification? Like all browser providers, we often have to make this decision. In this post, I’ll use some real-world JavaScript examples to illustrate some of the principles we use to deliver an interoperable browser when the standards specification isn’t enough.

In an ideal world, a standards specification is the complete story. A JavaScript implementation would just include everything in the ECMAScript specification and nothing more. We believe that specifications published by standards organizations such as Ecma International or the W3C are essential for interoperability among web browsers. Ideally, such specifications tell the browser implementers what features they need to provide and tell web developers what features they should be able to use.

In the real world of the web, things are not so clear-cut. Specifications are seldom perfect and sometimes they are intentionally incomplete or ambiguous. Having served as editor for the ES5 specification, I know that there are always issues that don’t get fully resolved. The result is that there are widely implemented and used features that are not defined by any standard specification. If you are trying to build a browser that runs the existing web you have to implement many features that are not defined by a standards specification.

What’s the Real Regular Expression Grammar?

We built Chakra by carefully following the ECMAScript 5 (ES5) specification including the grammar for regular expressions. But when we started testing on actual web sites we started seeing pages not work because of syntax errors on some regular expression literals. For example, we failed on regular expressions containing a right square bracket such as:

next = /]/.exec(buffer);

The reason was that the grammar for regular expressions in the ECMAScript standard includes ] in a list of characters that you cannot directly use as a match character. The specification says that /]/ is illegal and instead you need to say /\]/. It turns out that it is important that [ is restricted in this manner because otherwise it wouldn’t be possible to parse literals like /axyz[a-d]qwer/. However a lone ] that isn’t preceded by a [ really doesn’t present a parsing problem. But the standard still says that it is illegal.

In practice, all browsers accept regular expressions such as /]/ and web developers write them.

Consensus feature is a term we use to describe such features that are not part of any standard but which are universally implemented in an interoperable manner. In general, IE9 and any other new JavaScript implementation need to implement such consensus features in order to work with actual web content. The real challenge is identifying them, as they are not included in the standards specifications.

We recognize that we have to support these sorts of consensus features and we will also be working to make sure that they get included in future editions of the appropriate web standards. However, not all JavaScript extensions are universally or uniformly implemented.

Why Doesn’t IE9 have those _ _ methods?

ES5 includes support for getter/setter methods. Similar features have been available in some web browsers for many years. Over that period, browser developers experimented with various syntaxes and APIs for defining such methods. Prior to ES5, the most widely implemented API for defining getter/setter methods used two methods named __defineGetter__ and __defineSetter__. Surrounding method names with two underscore characters is a convention that some browser developers use to identify methods that are either experimental features or which access unique low level capabilities of a specific JavaScript implementation.

ECMA TC39 members agreed that getter/setter methods should be included in the ES5 specification because their value had been clearly demonstrated. However, TC39 also chose to design a new API for defining them and to not standardize the __defineXXX__ APIs.

Why did TC39 do this? Because of significant differences in the behaviors of the browsers that had provided that API. Standardizing on a common semantics for these methods would mean that some or perhaps all existing browser implementations would have to change to conform to the new semantics. That would probably break some applications that were written to work with those specific browsers.

Another reason was to maintain consistent naming conventions. No other built-in names in ECMAScript begin or end with underscore characters. The association of such names with experimental or an implementation specific feature is widely known and using that convention for a standardized feature would be both misleading and would dilute the utility of the convention for future experiments.

TC39 developed a new API based upon the Object.defineProperty method. This API not only supports defining getter/setter properties but also support other new capabilities of ES5. The __defineXXX__ methods were left out of the ES5 specification.

Browsers that already provide the __defineXXX__ API are free to continue to supporting them unchanged for compatibility reasons. However, new code that is written to be interoperable among browsers supporting the ES5 standard should use Object.defineProperty to define getter/setter properties.

We still get requests that we add the __defineXXX__ APIs to IE9. We understand why. Some developers already have code that uses those APIs and they would like that code run on IE9. However, we believe that supporting these APIs would not be in the best interests of the interoperable web. TC39 has already considered this API and concluded that it should not be standardized. If IE9 added support for the __defineXXX__ APIs, that action would move that API closer to being a permanent consensus feature of the web and would be essentially overriding the decision of TC39.

Unfortunately, in the short term this creates a small amount of additional work for developers currently using the legacy API. However, it is trivial to create a simple compatibility library for your code that implements the __defineXXX__ APIs in terms of Object.defineProperty.

A Malfunctioning Consensus Feature

Within JavaScript code, a function can be referenced and called in code that precedes the actual function declaration. This is possible because JavaScript logically “hoists” all function declarations to the top of the containing code body. JavaScript also allows more than one function declaration to exist for the same function name. Consider a simple test function:

function testFuncDeclarationOrder () {
   f1();
   function f1() {alert("first f1")}
   f1();
   function f1() {alert("second f1")}
   f1();
}

When called, this function produced the alert sequence: “second f1”, “second f1”,”second f1”. The reason is that JavaScript actually processes the function as if it had been written as:

function testFuncDeclarationOrder () {
   function f1() {alert("first f1")}
   function f1() {alert("second f1")}
   f1();
   f1();
   f1();
}

The ECMAScript specification has historically placed only one restriction upon the placement of function declaration. The ECMAScript standard does not include the ability to place a function declaration inside the body of a control structure statement. For example:

if (someCondition) {
   function f1() {alert("f1")}
}

The above code would produce a syntax error if parsed in according to the ECMAScript specification. However, if you try this in any browser, you will find that you do not get an error. Supporting function declarations anywhere a statement is permitted is a consensus feature of the web. If so, why wasn’t it included in ES5? Section 12 of the ES5 specification actually says something about this:

NOTE Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable difference, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

What does this dense statement mean? Simply stated, the behavior across different browsers varied so widely that reconciling them was impractical.

So what does IE9 do? Does it disallow such statement level function declarations as recommended by ES5? No, it treats such declarations exactly like previous versions of IE.

Why did we make that decision? Because previous experiments by browser implementers found that rejecting such declarations broke many existing web pages.

This may seem surprising. How can a web page rely on features that behave different across browsers and still be interoperable among browsers? One possibility is that the code isn’t actually used. It may be in a function that is never called or whose result is not essential to the operation of the page. However, if the JavaScript implementation treated these functions as syntax errors the entire script would be rejected even though the code is never called.

We don’t like having to implement a feature that is such a hazard for developers. But its existence is enshrined in the web so we really had no choice.

So What About const?

We are sometimes asked whether we will support the const declaration in IE9. const is a non-standard JavaScript extension that provides a way to declare “named constant” values. A typical usage might be something like:

const pi=3.14159;

Several browsers support this feature but there are significant differences in their handling of unusual situations and in what they define to be errors. Here is an example that shows some of the differing behavior among the browsers that “support” const:

// a function with multiple const declaration for the same name
function f() {
   alert('executing within f');
   const x=1;  //declare constant x as 1
   alert(x);
   const x=2;  //redeclare constant x as 2
   alert(x);
   x=3;        //try to assign 3 to x
   alert(x);
}
alert('about to call f'); f();

Depending upon the browser, running this code it might:

  • Issue a syntax error and not load the page.
  • Throw an exception when f is called.
  • Alert: '1', '2', '2'. This means conflicting const declarations are allowed but the assignment was ignored.
  • Alert '1', '2', '3'. This means that const was treated just like var.

Basically, only very simple uses of the const declaration are interoperable among browsers that support the declaration. Many more elaborate uses, or scenarios that might trigger some error condition, are not interoperable among those browsers.

An actual JavaScript implementation can’t only support the trivial common use cases. A real implementation also has to do something for all the odd edge cases and error scenarios that exist on real web pages. Arguably, it’s mostly for situations like this that we have standardized specifications. It’s generally pretty obvious what should be done for the simple common use cases. It’s the edge cases that require a standards specification in order to have interoperable implementations.

TC39 seriously considered including const in ES5 and it was in early ES5 drafts. However, there were many issues about how it should be defined and how it interacts with other declarations. Ultimately, there was agreement within TC39 that standardization of const should wait for the “next” edition of the specification where perhaps some of these other problems could also be addressed. Basically, TC39 decided it did not want to standardize on a flawed feature. Instead, it chose to defer any standardization of const for a future where a single improved design could be incorporated into all browsers.

So, what is IE9 doing with const? So far, our decision has been to not support it. It isn’t yet a consensus feature as it has never been available on all browsers. There is no standard specification and there are significant semantic differences among all the existing browser implementation. In addition, we know that TC39 decided not to standardize any of the existing alternatives and wants to reconsider it in the next ECMAScript revisions.

We understand the desire of many web developers to have such a declaration. But we also don’t want to create another situation like conditional function declarations where the feature has to exist but web developers better not use it if they care about browser interoperability. In the end, it seems like the best long term solution for the web is to leave it out and to wait for standardization processes to run their course.

Principled Decision Making

These are just four JavaScript specific examples illustrating the sort of decisions we have to make in creating IE9. Many similar issues come up with regard to other web standards and consensus features. For each we perform a similar analysis. What does the standard say? How many websites actually require it? Is it a consensus feature with a common semantics? Are there multiple, incompatible variants of the feature? Is a standards committee working on it? Do any test suites exist? Would our adoption help or hinder the standards processes? In the end it is a judgment call, and we try hard to make principled consistent decisions.

Allen Wirfs-Brock
Microsoft JavaScript Language Architect

 

Making Sites Look Their Best in Standards Mode

6:29 pm - August 23, 2010 in IEBlog

IE has traditionally drawn a 2-pixel border around the content area of a site. This border, drawn as part of the page rather than IE’s frame, affects calculations of distance from the top and left of the page. It also creates a not-so-modern beveled look.

In the fourth Platform Preview, you’ll notice pages running in IE9’s Standards Mode no longer have the border. Here’s a before and after:

Before
webpage with 2px border
After
webpage with no border

Pages that run in legacy document modes will still have a 2-pixel border so that any site calculations dependent on the 2 pixels remain the same as in IE8.

To make sure your site runs in IE9 Standards Mode and gets this and all the other latest features in IE9, use a strict doctype. We recommend the HTML5 doctype (<!DOCTYPE html>) since it’s simple and will put your site in Standards Mode in all current browsers.

John Hrvatin
Program Manager

 

Microsoft to Co-Chair New W3C Web Performance Working Group

6:34 pm - August 18, 2010 in IEBlog

Earlier this morning the W3C announced the formation of a new Web Performance Working Group chartered with making it easier to accurately measure web application performance. Enabling web developers to understand the real world performance characteristics of their applications is critical to the success of HTML5, and we’re excited to have been selected as co-chairs of the new working group alongside Google. We look forward to partnering with the W3C and the broader web community to enable these scenarios through an interoperable API.

The first deliverable for the working group is to recommend an API that measures the performance of browser navigations. The WebTimings specification provides a good starting point for these capabilities, so this specification will move into the Web Performance Working Group and become the foundation for our recommendations.

The third Internet Explorer 9 Platform Preview was the first browser to implement these portions of the WebTimings specification. Following standard conventions, we used a vendor prefix (ms) on the name because the specification was still under active development and hadn’t been brought into the charter of any working group. Google also recently provided an early implementation of these API’s inside Chrome using their vendor prefix (webkit). Through early collaboration between our engineering teams, we almost have interoperable implementations which is impressive for an API that has only been discussed for a few months. This is a great example of what’s possible through collaborative partnerships at the W3C.

With two early implementations available, it shouldn’t take long to finalize an interoperable API and remove the vendor prefixes. We can’t do this alone though - the new working group needs your feedback to ensure we have the right design. Over the next few weeks we’ll post more details on the working group website and begin to solicit feedback. In preparation, you can try out these API’s using the IE9 Platform Preview or Chrome 6 nightly builds. To help you get started take a look at the msPerformance demo on the IE9 TestDrive which shows these API’s in action.

Jason Weber
Lead Program Manager for IE Performance

 

IE9, Opacity, and Alpha

8:15 pm - August 17, 2010 in IEBlog

IE9 introduces support for the CSS3 Color Module, including its popular opacity property. As we have done with other standards-based features, opacity is implemented so that the same markup used in other browsers just works in IE9’s ­standard mode.

Internet Explorer 8 and earlier versions implemented an alternative mechanism to apply opacity using the alpha filter of the IE-specific filter property. This creates a compatibility challenge because IE9’s standard mode supports only opacity and not the alpha filter. (IE9’s compatibility modes Quirks, 7, and 8 still support the alpha filter but do not implement opacity.)

For sites that use best practice feature detection, this is not a problem. They will detect that opacity is supported in IE9 and use it instead of filter. The problem is with sites that use browser detection and mistakenly assume that IE always uses filter alpha instead of opacity and then change only the filter property in script. The opacity effect will appear broken in those Web pages when run in IE9’s default 9 document mode. The fix is to detect the standards-based opacity feature first and browser-specific filter feature second as we’ve described in previous posts.

Example Best Practice CSS

.fiftyPercentOpaque
{
opacity: 0.5;
filter: alpha(opacity=50);
}
Example Best Practice Code
// set flags for whether we should use opacity or filter with
// this browser (or browser mode). we prefer opacity.
var useOpacity =
(typeof document.createElement("div").style.opacity != 'undefined');
var useFilter = !useOpacity
&& (typeof document.createElement("div").style.filter != 'undefined');

function setOpacity(el, value) {
// let el be either an element object or an id string
if (typeof el == 'string')
el = document.getElementById(el);

// ensure value is in [0-1] range
value = Math.min(1, Math.max(value, 0));

// set opacity or filter alpha depending on what's supported
if (useOpacity)
el.style.opacity = value;
else if (useFilter)
el.style.filter = "alpha(opacity=" + (value * 100) + ")";
}
Alternative Browser-detection Code

In general, we prefer feature detection to browser detection but we’ve see a lot of opacity-related code use browser detection instead of feature detection.  If you have a site that does that today, you may find it easier to update your browser detection so it works with IE9. Here’s code that properly detects when IE is running in a browser mode less than 9’s standards mode.

function browserDetectSetOpacity(el, value) {
// let el be either an element object or an id string
if (typeof el == 'string')
el = document.getElementById(el);

// ensure value is in [0-1] range
value = Math.min(1, Math.max(value, 0));

if (navigator.userAgent.match(/\bMSIE\b/)
&& (!document.documentMode || document.documentMode < 9))
el.style.filter = "alpha(opacity=" + (value * 100) + ")";
else
el.style.opacity = value;
}
Summary

The problem described above occurs only when the opacity of an element is changed using script that doesn’t detect whether opacity is supported before changing filter. Sites that use only declarative CSS markup will continue to work fine even when opacity is changed indirectly by changing the CSS class of an element or using a pseudo-class such as :hover.

W3Schools offers a clear explanation of CSS opacity and IE’s legacy alpha filter.

—Ted Johnson, Program Manager Lead for Web Graphics

 

Add-ons, and Opting out of Google Analytics Without Them

2:30 pm - August 16, 2010 in IEBlog

Recently, Google made available the “Google Analytics Opt-out Browser Add-on.” This add-on enables consumers to “indicate that information about the website visit should not be sent to Google Analytics.” We agree that making it easy for consumers to protect their privacy is good, and Internet Explorer offers a variety of features to help keep you in control of your information when visiting websites. In this post, we describe how to use some of these built in features to accomplish the same outcome without installing a Browser Helper Object and the Google Update Service.

Users of Internet Explorer 7 and 8 (and soon 9) who wish to prevent Google Analytics’ script from running can follow these steps:

  1. In Internet Explorer, open the Tools tool icon menu and click Internet Options.
  2. Click the Security tab and then click the Restricted Sites icon.
  3. Click the Sites button.
  4. In the box at the top, add *.google-analytics.com and push the Add button.
  5. Click the Close button, and then the OK button to dismiss Internet Options.

After this configuration change, script from the Google Analytics website will not run on any webpage, and cookies will never be sent to the Google Analytics server.

Internet Options Restricted Sites dialog

How does this simple procedure work?  In IE7, we made a minor change to the Restricted Sites zone. IE will not run scripts that originate from sites the user places in the Restricted zone.

To protect your privacy further, IE will not send cookies to sites in the Restricted Sites zone.  In general, you can block script from any other domains by also adding those domains to the Restricted Sites zone.

Add-ons are useful and important. They are also a key cause of performance, stability, and security issues for all browsers. A more trustworthy approach involves building more functionality into the core browser and relying more on data (in the form of declarative descriptions, like XML) than code to extend the browser. For example, Accelerators in IE are XML descriptions of how to get a map, rather than arbitrary script that can get a map and possibly do more (like slow down the browser, or share more information than you’d like). Webslices are XML descriptions of parts of a webpage to show on IE’s Favorites Bar, rather than arbitrary script that can modify IE’s user interface and possibly do more than that under the hood.

In this situation, rather than install and run a lot of additional software on the machine, people can just add a web site to the Restricted Sites zone. Similarly, InPrivate Filtering in IE8 (and IE9) supports Importing and Exporting lists of sites that the user doesn’t want to exchange information with. That’s a simpler, safer, faster and more reliable approach than running more code.

Eric Lawrence
Program Manager

 
 
 
 
 
 
It's All About Search | © clsc.net |
2010.09.0319:31
Tech used here: Valid HTML - Valid CSS - Valid RSS - JavaScript - PHP - Smarty - MySQL - and a partridge in a pear tree.