Activate your free membership today | Log-in

Monday, February 1st, 2010

fullscreen API coming to browsers near you?

Category: Browsers

What can you do if you want to enable a fullscreen experience on the Web? You can't. Or, use Flash. Some claim that you shouldn't offer this ability as it is a security liability. Someone can put a fullscreen view that tricks the user into giving it information.

However, as much as I think user security is important, it doesn't seem like we can punt and not do anything because of this. A user agent can do a lot of things to help out.

Some (majority?) of the use cases revolve around full screen video. Eric Carlson has a WebKit checkin that enables that one case. You can webkitEnterFullScreen() on a HTML5 video element and be on your way.

You can see this in action on the SublimeVideo HTML5 player. Play the video in WebKit nightly and alt-click the "full size" arrows.

html5sublimevideo

Video is great, but what about general purpose? What if you could fullscreen any element? Robert O'Callahan threw up a strawman:

  1. Should be convenient for authors to make any element in a page display fullscreen
  2. Should support in-page activation UI for discoverability
  3. Should support changing the layout of the element when you enter/exit fullscreen mode. For example, authors probably want some controls to be fixed size while other content fills the screen.
  4. Should accommodate potential UA security concerns, e.g. by allowing the transition to fullscreen mode to happen asynchronously after the user has confirmed permission

New API for all elements:

JAVASCRIPT:
  1.  
  2. void enterFullscreen(optional DOMElement element, optional Screen, optional boolean enableKeys);
  3. void exitFullscreen();
  4. boolean attribute supportsFullscreen;
  5. boolean attribute displayingFullscreen;
  6. //"beginfullscreen" and "endfullscreen" events
  7.  

While an element is fullscreen, the UA imposes CSS style "position:fixed; left:0; top:0; right:0; bottom:0" on the element and aligns the viewport of its DOM window with the screen. Only the element and its children are rendered, as a single CSS stacking context.

enterFullscreen always returns immediately. If fullscreen mode is currently supported and permitted, enterFullscreen dispatches a task that a) imposes the fullscreen style, b) fires the beginfullscreen event on the element and c) actually initiates fullscreen display of the element. The UA may asynchronously display confirmation UI and dispatch the task when the user has confirmed (or never).

The enableKeys parameter to enterFullscreen is a hint to the UA that the application would like to be able to receive arbitrary keyboard input. Otherwise the UA is likely to disable alphanumeric keyboard input. If enableKeys is specified, the UA might require more severe confirmation UI.

In principle a UA could support multiple elements in fullscreen mode at the same time (e.g., if the user has multiple screens).

enterFullscreen would throw an exception if fullscreen was definitely not going to happen for this element due to not being supported or currently permitted, or if all screens are already occupied.

Much talking of exact API issues and more security.... but hopefully inertia does it job and we get something.

Would you like a fullscreen API?

Posted by Dion Almaer at 6:26 am
19 Comments

+++--
3.2 rating from 27 votes

Thursday, January 28th, 2010

Canvas Benchmark

Category: Browsers, Canvas, Performance

The Freeciv.net crew has benchmarked a path in their canvas game. It is one data point, and tests more than just Canvas itself because a lot of code is running in the game. Thus, it ends up testing the union of a particular JavaScript path and the rendering of the canvas.

Here are the results:

canvasbenchmark

With Bespin we had slightly different results, and the bulk of the bottleneck was in the blitting of the canvas. Optimizations were made to canvas over the initial phase of Bespin so the various browsers would leap frog each other. Good times :)

Posted by Dion Almaer at 6:09 am
26 Comments

++++-
4 rating from 28 votes

Thursday, January 14th, 2010

Adobe BrowserLab Update: More browsers, more features

Category: Adobe, Browsers

Adobe BrowserLab (formerly Meer Meer) has been updated today with new browsers and features:

  • New Browser Support: Adding Internet Explorer 8, Chrome 3.0, Safari 4 and Firefox 3.5 to the current list of supported browsers;
  • Rulers and Guides: Providing users more precision with rulers on the X and Y axes, as well as movable guides;
  • Move and Pan: Enabling users to move to any area of a screenshot; and
  • Screenshot Delay: Allowing users to pause rendering of a screenshot by up to 10 seconds for video-based content which requires time to let content load
  • Save Locally: Take your browser lab session with you as a jpg
  • Dreamweaver Extensions: Enhanced integration with Adobe Dreamweaver CS4

Are you finding it a useful tool as you develop on the cross browser cross platform Web?

Posted by Dion Almaer at 8:30 am
4 Comments

+++--
3.1 rating from 14 votes

Monday, December 21st, 2009

Chrome Extensions and webOS Applications look quite similar

Category: Browsers

Reposted from my personal blog

appsandextensions

"If you squint, Chrome Extensions and webOS applications look similar" -- a wise friend

Having now written webOS applications and Chrome Extensions I have been struck by how similar they are, and could be.

It may seem weird to see similarity in a browser extension mechanism and a mobile application runtime, but when you look at it, there is plenty to share at a high level:

Breaking out of the sandbox

Both worlds need to break out of the web browser sandbox. Extensions can't be restricted to the same limitations and Chrome Extensions have various API that relate to UI elements in the browser, as well as getting access to more.

On webOS we have exactly the same issue. When building native applications on webOS you can't have the same restrictions and thus new APIs, UI widgets, and services.

This issue goes beyond even these too worlds, and is one of the big challenges for Web runtimes in the near future. I expect my runtime to be able to do a lot more and to get access to my data not just through third party server side services, but locally too. This all brings us to...

Permissions

The Web needs a permissioning model. The sandbox doesn't give us enough, and although people quickly talk about security (which is critical) we forget what happens if the user can't do something through the Web. They often will download an .exe to their local computer and will just run it, not knowing anything about what it does.

A big challenge for us is to come up with a model that doesn't Do A Vista and drive our users nuts. We have to balance the desire to not ask the user for something all the time, while making sure the user knows what is happening. For power users at least, I favour the idea of showing me what is going on. Even if I grant an application a lot of power, if I could see when and what it was doing it would help. Of course, being able to restrict access to APIs is fantastic, especially when you get to layer social trust on top of the technical security. The Mozilla team talked a lot about just this and I look forward to more of their ideas and implementation.

(You can see an example of how Chrome does permissions with Cross site XHR.)

Application Bundle Info

The permissions and other metadata need to live somewhere. We have a appinfo.json file that has you declare info on your app. Chrome has a manifest.json.

On the Web we don't really have this. You hit a URL and you bootstrap from there. The HTML5 manifest does tell the browser which files are in scope for caching and the like, but that is about it. Applications and extensions can tell the system much more. You have ids, versions, pointers to update, icons, main launching points or not...

Headless Chickens

You don't often think of a headless web app. You can think of headless applications and extensions though. How many services are running on your computer now that have no UI? On webOS you can noWindow away and still provide value through the various services that we offer, the obvious being the rich and varied notification styles. Background apps are nicely supported.

Chrome Extensions have the notion of a background page as a way to manage a long lived lifecycle. Your background page is a singleton:

In a typical extension with a background page, the UI — for example, the browser action or page action and any options page — is implemented by dumb views. When the view needs some state, it requests the state from the background page. When the background page notices a state change, the background page tells the views to update.

In webOS and the Mojo framework we have a rich MVC system with a detailed lifecycle as well as the simple ability to define models, views and controllers.

And on

The more I look at these worlds, and others like them (e.g. Jetpack) the more I hope we come together. There are similar needs, and when you look from Chrome Extensions to Chrome OS, you can see a potential progression if done right.

My first post in the series talked about how the Web runtime is jumping out of the browser and giving us new areas to target our skills and code.

Posted by Dion Almaer at 6:00 am
10 Comments

++---
2.8 rating from 16 votes

Wednesday, November 18th, 2009

IE 9: Hardware rendering, new JS engine, CSS, standards, and more

Category: Browsers, IE

With PDC going on, we get a glimpse at the early stage of IE 9. There is some promise, albeit with omissions!

Dean Hachamovitch, IE general manager, gives us an early look whirlwind that discusses:

Performance Progress

The JavaScript engine team members John Montgomery, Steve Lucco and Shanku Niyogi give us an early look at the new JS engine that will ship with IE 9.

Standards / CSS

Although the Acid test score is low:

It is early days, and we do have rounded corners and CSS selectors!

Dean and his team talk over the work they are doing wrt standards.

Hardware acceleration

Finally, IE 9 will surf on the GPU using DirectX/D2D. As well as speeding up performance all around, setting the platform up for CSS transforms etc, we also see side benefits such as nicer fonts.

ie9fonts

What else have you heard from PDC?

Posted by Dion Almaer at 1:20 pm
40 Comments

+++--
3 rating from 39 votes

Tuesday, November 17th, 2009

Resource Packages; Making a faster Web via packaging

Category: Browsers, Performance

HTML:
  1.  
  2. <link rel="resource-package" href="site-resources.zip" />
  3.  

What if we could agree on a simple backwards compatible approach to packaging Web resources so the browser could suck down the puppies in one go?

Alexander Limi (of Plone and Firefox UX fame) has been thinking about this for awhile, and has gotten his latest proposal out there which defines a simple way to package things.

It builds on existing tech: zip, manifests, and the like.... and degrades nicely.

This is so much nicer than spriting hacks, but does have its own issues:

  • In theory the browser could sometimes render faster by grabbing items in parallel
  • Mobile caches may be messed up (as larger than a cache size, like say iPhone's 256k)
  • What if the zip gets out of date with the other resources?
  • Ideally tools (and in fact even web server modules) would auto generate this stuff

Although not perfect, for the majority case this could be a real boon to performance. What do you say Steve?

Oh, and it sounds like Firefox will implement this in 3.7!

Posted by Dion Almaer at 6:23 am
22 Comments

+++--
3.1 rating from 26 votes

Friday, November 13th, 2009

Lunascape Orion: Cross browser extensions

Category: Browsers

Lunascape 6.0 Orion is the latest version of the "triple engine" browser that lets you select between Gecko, WebKit, and Trident on Windows:

The latest version supports Firefox Add-ons as well as IE plugins, and they are quite bullish on their performance:

Posted by Dion Almaer at 6:37 am
15 Comments

++---
2.2 rating from 25 votes

Tuesday, November 10th, 2009

Sputniktests via Browsers

Category: Browsers, JavaScript, Standards

Sputniktests web runner is a web based porting of the Sputniktests ECMA-262 conformance test suite made by Google.

The aim of this test suite is to understand how compliant is a browser engine and the work @kangax has done in this post is, as usual, complete and loads of analysis about the test suite itself, and provided results.

So how do modern and not so modern browsers stand against standard? Here’s a comparison table (note that less score is better and that score represents total number of errors and failures)

null

The post goes through different engines behavior over apparently obvious results that could turn into a debug nightmare such:

JAVASCRIPT:
  1.  
  2. // what will happen, where, and why?
  3. for (var prop in null) { }
  4. for (var prop in undefined) { }
  5.  
  6. // is every "casted" space considered zero?
  7. Number("\u00A0") === 0
  8.  
  9. // is this statement correct?
  10. typeof new RegExp() === 'function'
  11.  
  12. // what if second argument is undefined?
  13. "test".substring(0, window.whatsup);
  14.  

I have personally never tried this test suite but accordingly with kangax, it seems to be worth it:

Having extensive compliance test suite can really help modern browsers achieve even better conformance. I hope we’ll see some of the bugs revealed through the Sputniktests fixed in the near future. I hope we’ll also see less regressions, if browser implementors integrate it into existing test suites. I also hope Sputniktests can help people learn and understand ECMAScript better.

Fun enough, Google Chrome does not score better than others but as the post says: it doesn’t always matter!

Last, but not least, Web runner is published on github, so that anyone can contribute easily. Thanks Juriy!

Posted by webreflection at 7:30 am
5 Comments

++++-
4.8 rating from 74 votes

Monday, November 2nd, 2009

Firefox 3.6 appearance adds a lot of developer features

Category: Browsers, Firefox, Mozilla

Firefox 3.6 is already on the scene with the first beta release. The Mozilla team is moving faster and faster these days which is fantastic to see.

At the high level:

  • Users can now change their browser’s appearance with a single click, with built in support for Personas.
  • Firefox 3.6 will alert users about out of date plugins to keep them safe.
  • Open, native video can now be displayed full screen, and supports poster frames.
  • Support for the WOFF font format.
  • Improved JavaScript performance, overall browser responsiveness and startup time.
  • Support for new CSS, DOM and HTML5 web technologies.

But there is so much more. There is a ton of CSS work including background-size, gradients, and multiple background images. Video can now have a poster frame, HTTP activity can be monitored, Web Workers can self-terminate with close(), drag and drop supports files via DataTransfer, window.onhashchange.

Posted by Dion Almaer at 6:30 am
7 Comments

++---
2.7 rating from 64 votes

Thursday, October 22nd, 2009

Client-Side tar and LZMA compression

Category: Browsers

The BrowserPlus team of Yahoo released a client-side compression API. As explained in the following screencast, the JavaScript API allows you to pack and compress files on the client with LZMA or tar.

Client Side Compression from Lloyd Hilaiel on Vimeo.

You can read more about the implementation or try out the live demo (requires BrowserPlus)

Browser Plus add-on to pack on the client side

Browser Plus add-on to pack on the client side

Using the API is as easy as calling the right method and sending it the files:

JAVASCRIPT:
  1. BrowserPlus.Tar.tar({'files':files});
  2. BrowserPlus.LZMA.compress({'files':files});

Both the LZMA and the tar extension are available on GitHub.

Posted by Chris Heilmann at 2:11 am
6 Comments

++---
2.5 rating from 46 votes

Tuesday, October 13th, 2009

Mobile WebKit Compatibility

Category: Browsers, Mobile

PPK has cried "There is no WebKit on mobile!" as he posts new compatibility tables that test WebKit across desktop and mobile:

I compare 19 WebKits in order to prove that there is no “WebKit on Mobile” and to figure out which one is the best. My hope is that eventually I’m going to gain some insight in the “family tree” of all WebKits.

This page only contains tests of CSS and JavaScript items that work in some WebKits but not in all. Adding more items, all of which are either supported by all or by none of the WebKits, makes no sense — it’s in the items in the table below that the differences between the 19 tested WebKits lie.

I will probably add some HTML5 items to this list later on, provided they’re supported by at least one WebKit (probably Safari or Chrome).

These tests focus solely on compatibility. I say nothing about performance or user interface, and especially on mobile these factors may, in the short run, be more important than compatibility.

webkitcompattests

Alex Russell responded to the concern that we are in a world of hurt with multiple browsers on mobile just like we are on the desktop. Alex thinks that the core notion of timeliness matters here:

I’m not convinced that the situation is nearly that bad.

The data doesn’t reflect how fast the mobile market changes. The traditional difference between mobile and desktop, after all, has been that mobile is moving at all. If you figure a conservative 24 month average replacement cycle for smartphones, then the entire market for browsers turns over every two years. And that’s the historical view. An increasing percentage of smartphone owners now receive regular software updates that provide new browsers even faster. What matters then is how old the WebKit version in a particular firmware is and how prevalant that firmware is in the real world. As usual, distribution and market share are what matters in determining real-world compatibility, and if that’s a constantly changing secnario, the data should at least reflect how things are changing.

He uses his own charts to make the comparison :)

alexrussellbrowserchart

What have you found?

Posted by Dion Almaer at 6:51 am
8 Comments

+++--
3.1 rating from 20 votes

Monday, September 28th, 2009

Going into details with the WebKit Page Cache

Category: Browsers, Safari

Brady Eidson has a great one two punch on the WebKit page cache. First, Brady delves into the basics of the page cache:

The Page Cache makes it so when you leave a page we “pause” it and when you come back we press “play.”

When a user clicks a link to navigate to a new page the previous page is often thrown out completely. The DOM is destroyed, Javascript objects are garbage collected, plug-ins are torn down, decoded image data is thrown out, and all sorts of other cleanup occurs.

When this happens and the user later clicks the back button it can be painful for them. WebKit may have to re-download the resources over the network, re-parse the main HTML file, re-run the scripts that dynamically setup the page, re-decode image data, re-layout the page, re-scroll to the right position, and re-paint the screen. All of this work requires time, CPU usage, and battery power.

Ideally the previous page can instead be placed in the Page Cache. The entire live page is kept in memory even though it is not on screen. This means that all the different bits and pieces that represent what you see on the screen and how you interact with it are suspended instead of destroyed. They can then be revived later in case you click the back button.

Then in part two we get deeper, and delve into the page show/hide events:

HTML:
  1.  
  2.    <html>
  3.     <head>
  4.     <script>
  5.  
  6.     function pageShown(evt)
  7.     {
  8.         if (evt.persisted)
  9.             alert("pageshow event handler called.  The page was just restored from the Page Cache.");
  10.         else
  11.             alert("pageshow event handler called for the initial load.  This is the same as the load event.");
  12.     }
  13.  
  14.     function pageHidden(evt)
  15.     {
  16.         if (evt.persisted)
  17.             alert("pagehide event handler called.  The page was suspended and placed into the Page Cache.");
  18.         else
  19.             alert("pagehide event handler called for page destruction.  This is the same as the unload event.");
  20.     }
  21.  
  22.     window.addEventListener("pageshow", pageShown, false);
  23.     window.addEventListener("pagehide", pageHidden, false);
  24.  
  25.     </script>
  26.     <body>
  27.     <a href="http://www.webkit.org/">Click for WebKit</a>
  28.     </body>
  29.     </head></html>
  30.  

Oh, and beware of plugins ;)

Secondly, a page might not be considered for the Page Cache because it’s difficult to figure out how to “pause” it. This happens with more complex pages that do interesting things.

For example, plug-ins contain native code that can do just about anything it wants so WebKit can’t “hit the pause button” on them. Another example is pages with multiple frames which WebKit has historically not cached.

Distressingly, navigating around these more advanced pages would benefit the most from the Page Cache.

Posted by Dion Almaer at 6:33 am
3 Comments

+++--
3 rating from 10 votes

Tuesday, September 22nd, 2009

Chrome Frame: Inject Chrome into IE

Category: Browsers, Google

Google has released the long anticipated Chrome Frame. Congrats to Alex Russell for getting this out. He fought browsers to bring us Dojo (with a great team) and now he comes at the problem in another way... from within.

What is Chrome Frame?

Let Alex tell you!

Put this in a page:

HTML:
  1.  
  2. <meta http-equiv="X-UA-Compatible" content="chrome=1" />
  3.  

and if a user comes to it using IE and has the plugin installed, the renderer will be replaced with Chrome.

If you want to help get the plugin installed, then you need to force it via JavaScript

HTML:
  1.  
  2. <script type="text/javascript"
  3. src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"> </script>
  4.  
  5. <div id="placeholder"></div>
  6.  
  7.  CFInstall.check({
  8.     node: "placeholder",
  9.     destination: "http://www.waikiki.com"
  10.   });
  11.  
  12.  

For testing, if you have it all installed, you can force the renderer via cf:http://gmail.com.

What does this mean?

We have a real problem. IE6 is a pain for Web developers. However, we have to remember that IE was the solution at some point.... we have an issue with getting new versions of the platform out there via browsers.

It will probably take Google a long time to get a large portion of the developers on browsers they want them to be on *cough*, so this is another tactic. The virus.

On one hand I applaud them for taking on the challenge, and I really believe that Alex has a good heart around this.

We do need to really think about what this means though. When is it developer choice, and when is it user choice? Who should control the experience? And, speaking of experience... how is the UX affected when you don't even know what renderer you are using, and items such as auto-fill just don't work on certain sites. Can the user override the developer? Will this be released on other browsers e.g. Safari/Firefox/Opera?

There are going to be massive ramifications with Chrome Frame, and we need to have a conversation around them. What are your thoughts?

Posted by Dion Almaer at 4:09 pm
40 Comments

++++-
4.2 rating from 79 votes

Monday, September 14th, 2009

BrowserScope: UAProfiler++, Crowd source browser tests

Category: Browsers, Performance, Testing

We are good friends with Steve Souders, but his UA Profiler just got beaten by something much better: BrowserScope. Fortunately for him, he and a new team are the ones who beat it :)

Lindsey Simon says it best:

Browserscope is an open-source project for profiling web browsers and storing and aggregating crowd-sourced data about browser performance.

The goals are to foster innovation by tracking browser functionality and to be a resource for web developers.

Browserscope is based on Steve Souders' UA Profiler, and his original tests have been preserved here as the Network test category. Other test categories include Ian Hickson's Acid3 test (ported by Jacob Moon into Browserscope), Annie Sullivan's Rich Text Edit Mode tests, and John Resig's Selectors API Test Suite (ported by Lindsey Simon into Browserscope).

This one more evolution, and more is to come:

  • Visualize test result trends over time
  • Wall of fame, up-and-comers, Billboard top 50
  • More test categories - cookies, security, reflow
  • More contributors
  • Tagged/personalized test results
  • Normalize time-based results across platforms
  • User agent parsing library

The guys are on hand to announce BrowserScope at The Ajax Experience this week!

Posted by Dion Almaer at 5:07 am
8 Comments

++++-
4.3 rating from 27 votes

Tuesday, September 1st, 2009

Web OS? Web VM? Value in both?

Category: Browsers, Editorial

The following post comes from my personal blog

Chrome OS created a whole slew of buzz around the Web finally being an OS. There are many other examples of this of course. On the desktop we have had the likes of moblin and Jolicloud for quite some time. On the phone we have webOS.

The Web as a virtual machine

In many ways, it seems obvious that this will happen. When I look at my desktop, I often find it looking like this:

browserasvm

which looks surprisingly similar to this:

windowsinmac

Wait a minute. Can't you look at the browser as being a virtual machine for the Web? A hugely successful one that has been ported to almost every platform known to man. It is a viral virtual machine that has become so successful due to its simple yet powerful constructs that allowed the platforms to do the porting (oh and it was friggin made to be free! Take that gopher!). As a virtual machine it grew so fast that it is quickly usurping the hosts themselves. The traditional operating systems. Applications are being written for the VM rather than the OS. This is very different to the diagram that has Windows running inside a VM on the Mac. In that case you are running applications written for Windows on the Mac. The virtualization crew have done wonders to make that emulation possible. With the Web you didn't quite need those tricks, and instead thanks to Web standards, you just had to write a browser.

Going inside out

Normally, we have seen systems built natively and then we virtualize them. In the case of the Web, the "Web platform" is the host environment and the VM. As this environment has become stronger and stronger, there is bound to be the time to ask "do we need our host anymore?" We are on the fringe of that time right now where a huge bulk of the applications that people use are Web based.

I just ran an experiment in this area myself. The hard drive in my Macbook Pro died and while the kind folks at the local Apple store replaced it I had to pick up a random machine for use. What would life be like if I had to work on a random machine? I purposely didn't restore from my own backup, and ended up with a week seeing how much of this cloud thing I use.

It turned out that all of the apps that weren't somehow cloud based were now a pain in the arse. Obviously I could get my email with Gmail and the other Web apps were there. However it went further than that. I could download Tweetie and be instantly up and running where I left off (thanks to the fact that Twitter is just a Web service). I got to see which IM servers did a good job keeping my server based contacts, and what a pain it is when you make changes on the local client to tell you that flubber65 is Frank and suddenly you have no idea who anyone is without that (NOTE: if you build a service, for gods sake save everything up there!).

It even made me happy for Bespin, as I was able to get to a bunch of my code. That has incentivized me to help make Bespin great :)

So, I learned that Web based services won. I was productive on a random machine in minutes, and cursed the situations where this wasn't the case (mainly around development).

If the entire OS was Web based, with a rich cloud infrastructure, then I could literally login to any machine and be ready to roll. X Windows productivity will be back! :) This will greatly change the role of devices too. Seamless upgrades. Multiple devices sharing data. Fun times.

So, Web OS it is. Hopefully the Web platform will be complete enough, and where it isn't this kind of force behind it will push it even faster (this is why I am excited to see the space heat up, and also wanting to keep a watchful eye to see how things get standardized with crazy timelines behind them).

What do we lose?

But, wait a minute. We have seen that virtual machines are actually pretty awesome. Having an entire system in a single file that I can suspend, backup, and run multiple off? Cool. I am running multiple "Web OS's" every day (Firefox, Safari, Chrome). I can update them whenever I want, and they can compete.

We also see fantastic features where we can watch over all of the connections from the virtual machine to the host. Tweak how ethernet works, set limits on various usage, etc. Just as we are getting amazing things out of virtual machines.... maybe we don't need the Web platform to move from there just yet.

User-Agent

Chris Beard (Chief Innovation Officer at Mozilla) is often talking about what it means for the browser to be the "users agent". There is so much that the s/browser/virtual-web-machine/g can be doing for us, and we have only just begun.

We need to be wary of losing out on any of these thoughts if the Web becomes the OS on the computer (whatever that means, of course!).

As we think about Jetpack and granting enhanced functionality from Web apps to browser-chrome I am often thinking about a morphing browser. When I am on Gmail, I don't need the URL bar and all of that jazz. Instead, add new Gmail specific UI for me to use, and let me tie into the local system for contacts etc.

In that vein, it has been nice to see a step in that direction when listening to Alexander Limi speak about UX in Firefox last week. He and the UX team showed some concept mockups for future versions of Firefox such as this:

By the "home" tab you can imagine other tabs that are for applications. Thin tabs that just have an icon (e.g. an email notification icon showing new message counts). These "app tabs" can be slightly magical. The user has to bless them, and at that time can grant special powers to access local services such as a File API, or a Webcam, or Geo location, or [insert cool thing that native apps can do]. This feels like a small step for the browser, but one that can open up a lot.

In conclusion, I am bullish about the Web being called the 'OS' on certain computing devices. I am most excited about seeing this driving innovation into the Web platform as a whole, and also exploring the great side of having a platform run as a virtual machine on your hardware. Gotta love the Web :)

Posted by Dion Almaer at 7:18 am
23 Comments

+++--
3.2 rating from 36 votes

Friday, August 28th, 2009

Creating a querySelector for IE that runs at “native speed”

Category: Browsers, CSS

Hello Ajaxians, my name is Paul Young and I am the co-founder of Skybound Software. We're the company behind Stylizer, which is a real-time CSS editing tool. We're taking a pretty radical approach to CSS editing, and as such, a lot of what I do is "web technology research", which is looking for better ways of doing things with a web browser, ultimately so that Stylizer can automate more of the web development process. This has allowed me the chance to discover a few things that have had significant impact on a web developer's workflow, as was the case with State Scope Image Replacement.

In conducting some research for a future version of Stylizer I found a way to create a querySelector method for IE 7 and lower. querySelector is a very useful feature of newer web browsers. It takes a CSS selector as string parameter and returns an array containing the HTML elements that match the selector. Unfortunately it doesn't work in IE 7 and lower... until now :)

My querySelector technique works in IE7 back to IE4 (although I only tested it back to version 6). It's only 327 characters minified, and runs ultra-fast because it doesn't parse strings or traverse the DOM. Keep in mind though that it's using the CSS selector engine built into the browser, which means no funky CSS 3 selector features will work, as they weren't implemented old versions of IE.

In order to explain how it works, I'll need to first cover something else I discovered: Single Execution CSS Expressions (SECEs). These are an enormously powerful technique that unfortunately has been made impossible in IE8. We're using these extensively in the built-in CSS reset feature in Stylizer to eradicate bugs and to add critical but missing features in IE 6 and 7.

About CSS Expressions

The problem with IE's CSS expressions feature is that because they're recalculated hundreds of times per second, they're notoriously slow. Fortunately, I've found a way to ensure they're only executed once per matched element. Examine the code below:

CSS:
  1.  
  2. DIV { -singlex: expression(this.singlex ? 0 : (function(t) { alert(t.tagName); t.singlex = 0; } )(this)); }
  3.  

There are 3 things you need to know to understand how this works:

  • CSS expressions are executed regardless of whether the CSS property name is valid. So "-singlex" is just an arbitrary name.
  • CSS expressions are executed on every matched element. So in the case above, on every div on the page.
  • Inside a CSS expression, the "this" keyword refers to the current matched HTML element.
  • The code above checks to see if the matched element has a property called "singlex". If it does, it just returns 0. Otherwise, it executes an inline function, passing it a reference to the matched element. Inside that function, we can perform whatever processing we want. At the end, we set a flag on the element to ensure that the function won't be executed again.

This is how you can do complex processing inside a CSS expression without having to worry about a performance hit. The function only executes on the first execution of the expression, and then on every subsequent execution, 0 is returned instantly. The performance cost of running an if test and returning 0 is negligible, even if you're doing it thousands of times per second. If you paste that CSS into a page with 3 div elements on it, in IE it will alert "DIV" 3 times.

The things you can do with SECE's are basically limited only by your imagination. Here is an example of using one to fake the CSS content property in IE 7 and lower:

CSS:
  1.  
  2. /* Newer browsers */ DIV:after { content: "Generated content!"; } /* IE 7 and lower */ DIV { -singlex: expression(this.singlex ? 0 : (function(t) { t.innerHTML += "Generated content!"; this.singlex = 0; } )(this)); }
  3.  

You can use SECEs to fake all sorts of things like generated content, min-width and min-height, CSS counters, CSS outlines, and more. But most importantly, you can...

Create a querySelector method with Single Execution CSS Expressions!

Creating a querySelector method is just a matter of dynamically adding a SECE to a page that copies a reference to each matched HTML element into a globally accessible array, and then returning that array. Examine the code below:

JAVASCRIPT:
  1.  
  2. /*@cc_on if (!document.querySelector) document.querySelector = function(selector) { // Add a new style sheet to the page var head = document.documentElement.firstChild; var styleTag = document.createElement("STYLE"); head.appendChild(styleTag); // Create a globally accessible element array document.__qsResult = []; // Create the SECE that copies all matched // elements to document.__qsResult. styleTag.styleSheet.cssText = selector + "{qs: expression(this.__qs?0:(function(t){document.__qsResult.push(t);t.__qs=0;})(this));}"; // Reflow the page. Without this, the SECE won't execute. window.scrollBy(0, 0); // Clean up and return head.removeChild(styleTag); return document.__qsResult; } @*/
  3.  

There you have it! The function is wrapped in a conditional compilation comment to make sure only IE 7 and lower can see it. Here is a minified version for convenience:

JAVASCRIPT:
  1.  
  2. /*@cc_on if(!document.querySelector)document.querySelector=function(s){d=document;h=d.documentElement.firstChild;t=d.createElement("STYLE");h.appendChild(t);d.__q=[];t.styleSheet.cssText=s+"{x:expression(this.__q?0:(function(t){document.__q.push(t);t.__q=0;})(this));}";window.scrollBy(0, 0);h.removeChild(t);return d.__q;}@*/
  3.  

I hope you can make use of SECEs and this querySelector method. Maybe it even has a place in jQuery? I don't know. (John Resig, are you reading? :)

UPDATE

After thinking this through a little further, I realized that you don't need to use a SECE at all for this, just a CSS expression added with JavaScript will do. Also, one of the commenters (Jordan1) pointed out that the code wouldn't return elements that had already been queried once. I've posted an update to the code below that should rectify the issue:

JAVASCRIPT:
  1.  
  2. /*@cc_on if (!document.querySelector)
  3.         document.querySelector = function(selector)
  4.         {
  5.             var head = document.documentElement.firstChild;
  6.             var styleTag = document.createElement("STYLE");
  7.             head.appendChild(styleTag);
  8.             document.__qsResult = [];
  9.            
  10.             styleTag.styleSheet.cssText = selector + "{x:expression(document.__qsResult.push(this))}";
  11.             window.scrollBy(0, 0);
  12.             head.removeChild(styleTag);
  13.            
  14.             var result = [];
  15.             for (var i in document.__qsResult)
  16.                 result.push(document.__qsResult[i]);
  17.             return result;
  18.         }
  19.     @*/
  20.  

NOTE: Fancy writing a guest post for Ajaxian? Got some tips on content that we haven't covered? Please email us, or tweet me :)

Posted by Dion Almaer at 6:13 am
32 Comments

++++-
4.3 rating from 43 votes

Next Page »