Last week, the W3C HTML Working Group reached a decision to publish several new working drafts and these are now available. The discussion about what to publish and how to structure the HTML5 specification has taken several months. In November, at the TPAC meeting, a request was made for the Microdata section of the specification to be removed. Back in August, I posted about our support for a separate Canvas 2D API specification.
Some people in the community raised concerns about exactly what should be in scope for the HTML working group. Tim Berners-Lee shared his thoughts:
“I agree with the WG chairs that these items -- data and canvas -- are reasonable areas of work for the group. It is appropriate for the group to publish documents in this area. On the one hand, they elaborate areas touched on in HTML4. On the other, these elaborations are much deeper than the features of HTML4, but also they form separate subsystems, and these subsystems have strong overlaps with other design areas. It is important (a) that the design be modular; (b) that the specifications be kept modular and (c) that the communities of expertise of the respective fields (graphics and data) be involved in the design process.”
We strongly support Tim’s call for modular design and modular specifications in web standards. Large monolithic documents are hard to consume and take longer to stabilise with well thought out engineering decisions. In fact, the decision to take these features from HTML5 and make them separate documents continues the process that started last year as the storage and networking APIs were moved out of HTML5 and into the W3C WebApps working group. Just like good software design, loose coupling and high cohesion are good principles for defining web standards. That doesn’t make them easy to apply and there is still more work to do to reduce the coupling between drafts. The group is working on improving the tools used to generate the documents to improve the cross-references, which will help towards this goal.
Microdata and Canvas 2D are now available as new working drafts alongside the core HTML5 draft. This also sets Microdata on a similar footing to the updated HTML+RDFa draft. You can review the full set of documents published yesterday here:
Adrian Bateman
Program Manager
For an industry that’s based on creativity and inspiring people, I don’t know why it’s so afraid. I don’t think it should be afraid to just try some crazy new stuff. But when I talk to people about online marketing, they just seem to freeze. … I thought this was going to be a much racier industry that wore black and got out there and rock and rolled and I see it being a little shier. I mean, I’m the crazy lady.
Tab isolation has recently become a more popular topic. This post is a quick survey of what tab isolation is, how it works, and what it provides.
What is it?
Tab isolation is a way to improve a browser’s reliability by containing the impact of a crash. Depending on how it’s implemented, tab isolation can also help contain some security attacks. There are two different implementations available today, each with different benefits.
In a tabbed browser without isolation, a problem in one tab can crash the entire browser. For example, a crash in a webpage in Firefox 3.6 or IE7 will bring down the entire browser. While modern browsers have features to recover tabs after a crash, the point of isolation is to contain the problem and prevent the browser from stopping. You can see a demo of this here (starting around 13:25).
A Quick Historical Survey
On March 5, 2008, Microsoft released the first IE8 beta with Loosely-Coupled IE (or LCIE for short). This was the first mainstream implementation of tab isolation. On September 2, 2008, Google Chrome’s first beta released with “process isolation.” Mozilla Firefox has recently discussed an “Out of Process Plugins” (OOPP) or Electrolysis project aimed at isolating Firefox plug-ins, such as Flash, from the rest of the browser.
How do isolation approaches differ today in approach and benefits?
There are a lot of different subsystems in a browser to isolate from each other, and different ways to do it.
IE8 isolates the frame process (title bar, back button, address bar, etc.) from the tabs processes (that show web pages). If anything causes a site to crash (an extension like Flash, or the rendering or scripting engine, etc.), the frame and other tab processes will not crash. IE isolates the whole tab – all of its code, data, and extensions – to keep IE resilient to webpages with issues.
In addition to using multiple processes, IE8 on Windows 7 and Vista (and IE7 on Vista) sandboxes the tab processes in Protected Mode for security reasons. Specifically, tabs run without permissions to install software, modify settings, or change files of any user. Protected Mode provides defense in depth so that (in most cases) security vulnerabilities in the browser or an add-on (like Flash) cannot be exploited to harm the computer. Isolation makes this additional security possible. (Technically, there are several different types of isolation (process isolation, origin isolation, etc.), and of sandboxing (integrity levels, restricted subsets, DOM mirroring, etc.) as well.)
Chrome’s isolation is a bit different, factoring the different subsystems of that browser along different lines. From their documentation, they have separate processes for rendering, for the frame, and for add-ons (native plug-ins, not extensions). As with IE7, part of Chrome runs with lower privilege. Unlike IE (where page add-ons run in low), plugins in Chrome by default run with more privileges. As with any architectural difference, there are scenarios that are better in one architecture and worse in another. Theoretically, for example, a vulnerability in the Flash control running in Chrome does not have a defense in depth protection like Protected Mode to contain it.
Isolation is a super important part of modern browsers. It’s essential for delivering a more reliable browsing experience. It can also improve security. Depending on how it’s engineered, it can also have an impact on compatibility with sites and browser extensions.
Andy Zeigler
Program Manager
Tom Hughes-Croucher is an evangelist for the Yahoo! Developer Network.
Our friends over at JSMag are celebrating their first birthday. If you haven’t read JSMag it’s a monthly PDF magazine that covers news on hot JavaScript topics and provides practical tutorials.
JSMag are giving away a free issue from their first year. Simply log into your JSMag account and use the code ‘oneyear’ to get a free issue.
When selecting your free issue, you may want to seek out the articles in JSMag written by Yahoos frontend engineers or about YUI over the last 12 months:
Happy Birthday, JSMag!
There are many tools in the market that allow you to customize your pages' cascading style sheets (CSS), but there are actually a very few that do the opposite—scan for all the CSS rules in the document and remove those that are not used. Cleaning out the CSS will not only reduce the bandwidth impact, but will also improve the performance of the browser (minimizing the time spent by the CSS engine to parse the style sheets).
In this post, I will describe how to build that tool using a bookmarklet and a new standard function introduced in Internet Explorer 8: document.querySelectorAll().
Let’s start with the basics: a Web page can include many cascading style sheets, each of which is composed of one or more selectors. For instance, #elementId { }, .className { }, and body{ } are each examples of selectors. Using the function querySelectorAll(), you can programmatically inspect the DOM tree and count the number of times each selector is actually used.
For instance, the following code snippet counts the number of times the CSS class Foo is used in the document:
var selectorCount = document.querySelectorAll(“.Foo”).length;
Now that we have this information, we need a way to run this script inside the document. For the purpose of this article, I didn’t want to change our server-side code.
I decided to create a bookmarklet, which is a special link that can interact dynamically with the currently loaded page. The syntax of the bookmarklet is fairly straightforward:
<a href="javascript:(
function() {
var c = document.createElement('script');
c.type = 'text/javascript';
c.src = 'http://demos.cloudapp.net/IE/CssCrunch/Scripts/CssCrunch.js';
document.getElementsByTagName('head')[0].appendChild(c); })();">
CSS Crunch
</a>
As you can see, at runtime this injects a remote script file that runs the analysis and displays the result.
If you scroll to the bottom of the list of CSS rules, you’ll see an option to remove temporarily unused selectors. This allow you to test if the page still displays and behaves the same way, as shown in the picture below.
I’d like to stress the fact that the goal is not to reach 100% usage on any page; there are scenarios in fact where the same style sheet could possibly be used by multiple pages and it makes sense to pre-fetch some rule, or where the page compression balance well having additional styles to maintain. Instead you should use this tool to identify possible areas for improvement.
That’s it! You can try it here:
This is just a starting point; if you are interested in doing more, you can find the source code here. I encourage you to look at the underlying code and customize it to suit your needs. For example, you might want to add support for multiple-pages analysis, or integration with server-side tools such as Visual Studio or IIS, or a compression capability such as Microsoft Ajax Minifier.
Ok, time to go! I'm checking the CSS on this blog now… :)
Have fun!
Giorgio Sardo
Web Technical Evangelist
Microsoft Corporation
Stephen Woods works on frontend platforms at Yahoo! and has been working closely with YUI 3 and technologies related to the Yahoo! Home Page during the past year. You can find him at @ysaw and at stephenwoods.net
I was working on an internal product here at Yahoo! that required users to input time-of-day in a specific format. I decided that rather than force users to type exactly the right format it would be easier just to provide a UI widget for time input. I’ve always liked the jQuery timepicker; it’s a simple and fast way to input time and meets my use case perfectly. Of course, we were using YUI 3, so I decided to recreate the widget with YUI 3. (This is quick and easy with the YUI 3 Widget foundation.) I thought it might be useful to others working with YUI, so I decided to give it right back to the community for use in your own projects.
Using the picker should be pretty simple for you if you are familiar with the basics of YUI 3. (see a live version here).
To use the picker in your own project include the script:
<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.0.0/build/yui/yui-min.js&gallery-2010.02.25-22/build/gallery-timepicker/gallery-timepicker-min.js"></script>
Then instantiate and render the widget:
YUI().use('gallery-timepicker', function(Y){
//Pass a configuration object to the timepicker
var picker = new Y.Saw.Timepicker(
{
//an element that will contain the timepicker
contentBox: 'div.foo',
/the initial time
time:{
hour:0,
minute:0
},
strings:{
am:'AM',
pm:'PM',
seperator:':'
},
delay:5 //delay before selecting a box on mouseover
}
);
picker.render();
});
Like all YUI 3 widgets the timepicker constructor takes a configuration object to control the initial display of the widget. Manipulating the widget is then done via the widget methods render, hide and show. The render method is where the actual DOM elements are created. hide and show simply add and remove the class yui-timepicker-hidden to the elements bounding box. This class (and the additional css classes for the widget) must be implemented for the widget to behave properly. For simplicity’s sake, here are the styles I am using on the running example:
/* yui reset assumed */
.yui-timepicker{
display: block;
margin: 5px;
left: 0;
position: relative;
background: transparent;
}
/* standard for widgets, in this case just pushing the hidden one off the screen*/
.yui-timepicker-hidden{
left: -9999em;
position: absolute;
}
.yui-timepicker{
color: #000;
font-family: verdana;
text-align: left;
}
/* the picker is actually two ordered lists */
.yui-timepicker ol{
display: block;
position: relative;
left: 0;
.left: 5px;
margin: 0px;
padding: 0px;
height: 24px;
text-align: left;
-webkit-transition: left .1s ease-in;
}
.yui-timepicker li{
list-style: none;
display: block;
float: left;
position: relative;
left: 0;
overflow: hidden;
width: 19px;
padding: 1px;
margin: 0 2px 0 0;
border: 1px solid #999;
text-align: center;
}
.yui-timepicker li{
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
/* highlight the selected times */
.yui-timepicker li.yui-timepicker-active{
background: #000;
color: #fff;
-moz-box-shadow: 2px 2px 2px #ccc;
-webkit-box-shadow: 2px 2px 2px #ccc;
}
I’m using webkit animations just for style; for your project, customize these styles as you see fit. For most purposes you will want to hide the picker initially. Calling the hide method just adds the yui-timepicker-hidden style to the widget’s bounding box. I’ve added a click handler to my wrapper element so that a click on the element with the id time will cause the widget to appear/disappear:
picker.hide();
Y.get('#main').on('click', function(e){
var target =e.target;
if(target.test('#time')){
picker.toggle();
}
});
To make the picker actually useful I will listen to the
timeset
event, which returns an object with information about the selected time, I’m going to use the “s24hour” member of the object passed to the handler. That’s a string representation of the time in 24 hour format. (also available are hour, minute, ampm and s12hour):
picker.subscribe('timeset', function(e){
//timeset is a custom event that fires when the time is *set*
//use this rather than timeChange
Y.get('#time').set('value',e.s24hour);
});
//add a handler to "cell click" to hide the picker when the user clicks on a cell
picker.subscribe('cellclick', function(e){
this.hide();
},picker);
That’s all there is to it! Enjoy.
Continuing the Crockford on JavaScript lecture series (Videos: Part One, Part Two, Part Three), Douglas will be presenting Wednesday at Yahoo! headquarters in Sunnyvale, CA. Attendance is free, but seating is limited (a few tickets remain for each of the final shows) — a full schedule including links to RSVP is available on the event website.
Wednesday’s session is entitled “Episode IV: The Metamorphosis of Ajax.” We hope to see you there.
Thanks to YUI engineer Allen Rabinovich for the poster design.
This post describes how IE8 determines what Document Mode such as Quirks or Standards Modes to use for rendering websites. This topic is important for site developers and consumers.
It’s related to the Compatibility View List that we recently updated. This list is down by over 1000 websites, from over 3100 to just over 2000, since IE8 released last March. As we work with site developers and standards bodies, we’re excited to see the sites that need to be on the Compatibility View (CV) List continue to go down.
Data-driven Design
Before we dig in to the design details, I want to share some of the data we use to design the compatibility experience.
When looking at the doctype and X-UA-Compatible meta tag and header on thousands of high traffic websites worldwide such as qq.com, netlog.com and those on the initial CV List,
Here’s why this makes sense; many high traffic websites want to render in as many browsers as possible, which is why they write for Quirks. Many websites have pages written specifically for IE7 and many web authoring tools such as Aptana Studio and Expression Web specify the Transitional doctype by default:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Thinking in terms of web-scale, there are billions of pages written specifically for either Quirks, IE7, Almost Standards, or the latest Standards. IE needs to support all of these web platform variations to ensure that our broad, world-wide, user-base has the best experience.
With this data in hand, we designed IE8 with a few principles in mind:
As stated in previous posts, we’re committed to interoperability, which means rendering websites in the most standards compliant way possible by default.
A small set of users will tinker to get websites that expect and work best in IE7 Standards Mode to work in IE8’s more standards-compliant default mode. For everyone else, IE8 includes Compatibility View Settings.
The best experience here is one that works automatically as the web developer intended. This is why we created the Compatibility View List. It’s also important to give users the ability to fix websites that aren’t on the list yet through the Compatibility View button.
The X-UA-Compatible meta tag and header override IE and user settings. They also provide web developers with fine-grain control over how each webpage renders in IE.
For example, some websites have pages written for Quirks and others for IE7 Standards. When IE receives an X-UA-Compatible header with an EmulateIE7 value from servers, it renders each page in the appropriate Quirks or IE7 Standards Mode.
IE8 introduced the X-UA-Compatible meta tag and header to provide web developers time to transition their websites to IE8 Standards. As mentioned above, many websites have already used this mechanism to specify that their content should run in IE7 Standards Mode.
A Diagram on How IE8 Determines Document Mode
Given the above principles, there are four rules that you can remember about how IE handles doctype, X-UA-Compatible meta tag and header, Developer Tools, and Compatibility View Settings. These rules follow the diagram below from top to bottom:
Compatibility and interoperability are complex. To reduce complexity for developers and users alike, we would love to see websites transition from legacy browser modes. We respect that the choice of mode is up to the site developer. We’re excited to work with sites and standards bodies to continue improving IE’s implementation of interoperable standards.
Many thanks to Jesse Mohrland for verifying the diagram.
Marc Silbey
Program Manager
About the Author:
Philippe Bernou is the founder and CEO of the French startup EtreProprio.com, a real estate website for individuals. After working for four years in Luxemburg on IBM technologies, he launched EtreProprio.com in 2008 with Aurélie Eav.
EtreProprio.com aims to provide high quality classifieds for free (see an example of a listing here). There are currently more than five thousand property owners selling their houses on EtreProprio.com. We wanted to provide a simple but powerful interface, and we needed a lot of front-end logic. After a little experimentation, we chose YUI which struck us as powerful, robust, very well documented and highly customizable. As a consequence, EtreProprio.com is using YUI (2.8.0) heavily for its front-end.
The following modules are used:
Let’s go deeper on three implementations: Advanced Search, Photo Uploader and TabView.
The form used to find properties is developed on top of AutoComplete and Dual Slider. The labels above slider thumbs are positioned by listening to change event. Then, they are repositioned if a collision occurs between min and max labels. The AutoComplete implementation can display mixed elements such as cities, postal codes or regions. Each element has its own display format.
We used YUI’s Uploader, DataTable and Drag and Drop modules in order to create simple form for photo uploading. First, the user selects the photos on his computer. Then he clicks “Send all” and as the photos are sent, a table below is populated with the photos and details. Drag and drop is applied to the rows of the table, it allowing users to easily reorder the photos. The description of each photo can be modified using a simple text input and YUI’s XMLHttpRequest utility, Connection Manager.
See the video below for a demonstration:
As there is a lot of information to display in a classified detail, we used TabView to design the page. The CSS personalization capabilities of TabView allow us to integrate it perfectly with the rest of the page from a design perspective. Tabview also saves us bandwidth as only interested users click on all the tabs — TabView has support for lazyloading Tab content, and that pattern works well for us here.