Categories

YUI Graded Browser Support

A-Grade Browser Support Chart

This chart lists browsers that receive A-grade support as defined by Graded Browser Support. All YUI projects, including YUI 2 and YUI 3, aim to provide full A-grade support.

Win XP Win Vista Mac 10.5.† Mac 10.6.†
Firefox 3.0.† A-grade
Firefox 3.5.† A-grade A-grade A-grade
Opera 10.0.† A-grade
IE 8.0 A-grade A-grade
IE 7.0 A-grade A-grade
IE 6.0 A-grade
Safari 4.0.† A-grade A-grade
  • The dagger symbol (as in “Firefox 3.5.†”) indicates that the most-current non-beta version at that branch level receives support.
  • Code that may be used on pages with unknown doctypes should be tested in IE7 quirks mode.
  • Code that may appear in IE8’s “compatibility mode,” which emulates but is not identical to IE7, should be tested explicitly in compatibility mode.

C-Grade Browser List (Draft)

This list represents browsers from which CSS and JavaScript should be withheld. This list is in draft status. Discussion of the C-Grade list and the A-Grade matrix takes place in the comments section of the latest GBS update.

  • IE < 6 (including Mac OS versions)
  • Safari < 3
  • Firefox < 2
  • Opera < 9.5
  • Netscape < 8

We recommend testing your C-Grade experience in one of the above browsers or in a modern browser with JavaScript and CSS disabled. As part of your standard QA process, verify that JavaScript and CSS resources are withheld from the above browsers based on user agent.

GBS Updates Archive

This page is the permanent home of the current A-Grade chart. Updates are publicized on the YUI Blog. You may always reference past updates on the blog via the links gathered here.

  • GBS Update, 2009 Q4
  • GBS Update, 2009 Q3
  • GBS Update, 2009 Q1
  • GBS Update, 2008 Q3
  • GBS Update, 2008 Q1

Graded Browser Support: What and Why

In the first 10 years of professional web development, back in the early ‘90s, browser support was binary: Do you — or don’t you — support a given browser? When the answer was “No”, user access to the site was often actively prevented. In the years following IE5’s release in 1998, professional web designers and developers have become accustomed to asking at the outset of any new undertaking, “Do I have to support Netscape 4.x browsers for this project?”

By contrast, in modern web development we must support all browsers. Choosing to exclude a segment of users is inappropriate, and, with a “Graded Browser Support” strategy, unnecessary.

Graded Browser Support offers two fundamental ideas:

  • A broader and more reasonable definition of “support.”
  • The notion of “grades” of support.

What Does “Support” Mean?

Support does not mean that everybody gets the same thing. Expecting two users using different browser software to have an identical experience fails to embrace or acknowledge the heterogeneous essence of the Web. In fact, requiring the same experience for all users creates an artificial barrier to participation. Availability and accessibility of content should be our key priority.

Consider television. At the core: TV distributes information. A hand-cranked emergency radio is capable of receiving television audio transmissions. It would be counter-productive to prevent access to this content, even though it’s a fringe experience.

Some viewers still have black-and-white televisions. Broadcasting only in black-and-white — the “lowest common denominator” approach — ensures a shared experience but benefits no one. Excluding the black-and-white television owners — the “you must be this tall to ride” approach — provides no benefit either.

An appropriate support strategy allows every user to consume as much visual and interactive richness as their environment can support. This approach—commonly referred to as progressive enhancement — builds a rich experience on top of an accessible core, without compromising that core.

Progressive Enhancement vs. Graceful Degradation

The concepts of graceful degradation and progressive enhancement are often applied to describe browser support strategies. Indeed, they are closely related approaches to the engineering of “fault tolerance”.

These two concepts influence decision-making about browser support. Because they reflect different priorities, they frame the support discussion differently. Graceful degradation prioritizes presentation, and permits less widely-used browsers to receive less (and give less to the user). Progressive enhancement puts content at the center, and allows most browsers to receive more (and show more to the user). While close in meaning, progressive enhancement is a healthier and more forward-looking approach. Progressive enhancement is a core concept of Graded Browser Support.

What are Grades of Support?

While an inclusive definition of browser support is necessary, the support continuum does present design, development, and testing challenges. If anything goes, how do I know when the experience is broken? To address this question and return a sense of order to the system, we define grades of support. There are three grades: A-, C-, and X-grade support.

Before examining each grade, here are some characteristics useful for defining levels of support.

Identified vs. Unknown There are over 10,000 browser brands, versions, and configurations and that number is growing. It is possible to group known browsers together.

Capable vs. Incapable No two browsers have an identical implementation. However, it is possible to group browsers according to their support for most web standards.

Modern vs. Antiquated As newer browser versions are released, the relevancy of earlier versions decreases.

Common vs. Rare There are thousands of browsers in use, but only a few dozen are widely used.

The Three Grades of Support

C-grade

C-grade is the base level of support, providing core content and functionality. It is sometimes called core support. Delivered via nothing more than semantic HTML, the content and experience is highly accessible, unenhanced by decoration or advanced functionality, and forward and backward compatible. Layers of style and behavior are omitted.

C-grade browsers are identified on a blacklist.

Summary: C-grade browsers are identified, incapable, antiquated and rare. QA tests a sampling of C-grade browsers, and bugs are addressed with high priority.

A-grade

A-grade support is the highest support level. By taking full advantage of the powerful capabilities of modern web standards, the A-grade experience provides advanced functionality and visual fidelity.

A-grade browsers are identified on a whitelist. Approximately 96% of our audience enjoys an A-grade experience.

Summary: A-grade browsers are identified, capable, modern and common. QA tests all A-grade browsers, and bugs are addressed with high priority.

X-grade

X-grade provides support for unknown, fringe or rare browsers as well as browsers on which development has ceased. Browsers receiving X-grade support are assumed to be capable. (If a browser is shown to be incapable — if it chokes on modern methodologies and its user would be better served without decoration or functionality — then it should considered a C-grade browser.)

X-grade browsers include all browsers not on the C-grade blacklist or the A-grade whitelist

Summary: X-grade browsers are assumed to be capable and modern. QA does not test, and bugs are not opened against X-grade browsers.

The Relationship Between A- and X-grade Support

A bit more on the relationship between A and X grade browsers: One unexpected instance of X-grade is a newly-released version of an A-grade browser. Since thorough QA testing is an A-grade requirement, a brand-new (and therefore untested) browser does not qualify as an A-grade browser. This example highlights a strength of the Graded Browser Support approach. The only practical difference between A and X-grade browsers is that QA actively tests against A-grade browsers.

Unlike the C-grade, which receives only HTML, X-grade receives everything that A-grade does. Though a brand-new browser might be characterized initially as a X-grade browser, we give its users every chance to have the same experience as A-grade browsers.

Quality Assurance (QA) Testing

Grading the browser ecosystem enables meaningful, targeted, and cost-effective QA testing. As noted, representative C-grade testing and systematic A-grade testing ensures a usable and verified experience for the vast majority of our audience. A-grade testing must be thorough and complete, while C-grade testing can be accomplished with one or two representative browsers (e.g., Netscape 4.x and Lynx), or by using a modern browser with CSS and JavaScript disabled.

It’s worth reiterating that testing resources do not examine X-grade browsers.

Representative testing of the core experience is critical. If you choose to adopt a Graded Browser support regime for your own web applications, be sure your site’s core content and functionality is accessible without images, CSS, and JS. Ensure that the keyboard is adequate for task completion and that when your site is accessed by a C-grade browser all advanced functionality prompts are hidden.

In Conclusion

Graded Browser Support provides an inclusive definition of support and a framework for taming the ever-expanding world of browsers and frontend technologies.

Tim Berners-Lee, inventor of the World Wide Web and director of the W3C, has said it best:

“Anyone who slaps a ‘this page is best viewed with Browser X’ label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network.”

YUI on Mobile

YUI generally works well with mobile browsers that are based on A-Grade browser foundations. For example, Nokia’s N-series phones, including the N95, use a browser based on Webkit — the same foundation shared by Apple’s Safari browser, which is found on the iPhone. The fundamental challenges in developing for this emerging class of full, A-Grade-derived browsers on handheld devices are:

  • Screen size: You have a much smaller canvas;
  • Input devices: Mobile devices generally do not have mouse input, and therefore are missing some or all mouse events (like mouseover);
  • Processor power: Mobile devices have slower processors that can more easily be saturated by JavaScript and DOM interactions — and processor usage affects things like battery life in ways that don’t have analogues in desktop browsers;
  • Latency: Most mobile devices have a much higher latency on the network than do terrestrially networked PCs; this can make pages with many script, css or other types of external files load much more slowly.

There are other considerations, many of them device/browser specific (for example, current versions of the iPhone’s Safari browser do not support Flash). The goal of these sections on YUI User’s Guides is to provide you some preliminary insights about how specific components perform on this emerging class of mobile devices. Although we have not done exhaustive testing, and although these browsers are revving quickly and present a moving target, our goal is to provide some early, provisional advice to help you get started as you contemplate how your YUI-based application will render in the mobile world.

YUI 2: YUI Loader Utility

The YUI Loader Utility is a client-side JavaScript component that allows you to load specific YUI components and their dependencies into your page via script. YUI Loader can operate as a holistic solution by loading all of your necessary YUI components, or it can be used to add one or more components to a page on which some YUI content already exists.

YUI Loader adds value in the following ways:

  1. Reliable, sorted loading of dependencies: YUI comprises more than two-dozen components, many of which work together to provide the best possible compromise between compartmentalization and code reuse. Because of this, YUI components often need to load with specific dependencies in a specific order. YUI Loader understands which components depend on one another, and based on this knowledge it ensures that the right resources are loaded in the right order.
  2. Safe, efficient mechanism for adding new components to a page on which YUI may already be present. Often as developers we write modules that can live in many contexts. In writing a module, we may need to support a variety of scenarios — the module may be introduced into a page on which all of its YUI dependencies are already present, a page on which some but not all are present, or a page on which no YUI content exists at all. YUI Loader looks at the environment as it exists on the page and pulls in only the additional files your module needs to function.
  3. Automatic use of rolled-up files. YUI Loader knows about all of the built-in rollup files that ship with YUI — like the yahoo-dom-event.js file that contains the Yahoo Global Object, the Dom Collection, and the Event Utility, three components that are commonly used together. By automatically using rolled-up files when it makes sense to do so, the YUI Loader helps you reduce HTTP requests and thereby keep your page as efficient as possible.

As you think about how you want to load YUI on the page, you may find it useful to refer to this overview of some of the most common loading strategies and their relative merits:

  • “Loading YUI: Seeds, Core, and Combo-handling”, by Eric Miraglia on YUIBlog

Note: It’s important to emphasize that any client-side loading utility is expected to be somewhat less performant than solutions that write <script> and <link> elements directly to the page. The use of dynamic <script> and <link> nodes provides good performance and a useful mechanism for bringing in additional JavaScript or CSS after the page has loaded, but for optimal performance you may still wish to write CSS <link> elements to the head of the page and JavaScript <script> elements to the bottom of the page during its initial load.

YUI 2: Uploader

YUI Uploader provides file upload functionality that goes beyond the basic browser-based methods. Specifically, the YUI Uploader allows for:

  1. Multiple file selection in a single “Open File” dialog.
  2. File extension filters to facilitate the user’s selection.
  3. Progress tracking for file uploads.
  4. A range of available file metadata: filename, size, date created, date modified, and author.
  5. A set of events dispatched on various aspects of the file upload process: file selection, upload progress, upload completion, etc.
  6. Inclusion of additional data in the file upload POST request.
  7. Faster file upload on broadband connections due to the modified SEND buffer size.
  8. Same-page server response upon completion of the file upload.

Important Issue: Due to a current bug, the current version of uploader.swf hosted on yui.yahooapis.com in the YUI 2.8 branch is NOT compatible with the uploader.js hosted on yui.yahooapis.com. Until the next bugfix release, you can work around this issue by either locally hosting the older version of uploader.swf (available here), or locally hosting the uploader.js and making the following changes to it:

  • On line 509, in swfObj.addVariable("elementID", swfID);, replace “elementID” with “YUISwfId”.
  • On line 512, in swfObj.addVariable("eventHandler", "YAHOO.widget.FlashAdapter.eventHandler");, replace “eventHandler” with “YUIBridgeCallback”.

Important usage notes:

  • Because of security changes in the upcoming Flash Player 10, the UI for invoking the “Browse” dialog has to be contained within the Flash player. Because of that, this new version of the Uploader is NOT BACKWARDS COMPATIBLE with the code written to work with the previous version (it is, however, compatible with Flash Player 9). Do not upgrade to this version without carefully reading the documentation and reviewing the new examples.
  • The Uploader Control should always be served from an HTTP server due to Flash Player’s restricted local security model.
  • The Uploader Control requires Flash Player 9.0.45 or higher. The latest version of Flash Player is available at the Adobe Flash Player Download Center.

Note: The Uploader Control is being released as a beta component. Please refer to the FAQ for what we mean by this designation. We look forward to your feedback in the YUI Forums.

Google Gears on Wordpress and Myspace

Speed Up Static Resources

Gears can speed up your web application using the LocalServer module. WordPress, a popular blogging platform, uses Gears and the LocalServer module to significantly improve the performance of common operations. WordPress incorporates a rich text editor that makes authoring posts much easier. However, this editor has a ton of associated resources, such as CSS, JavaScript, images, etc. (more than a hundred!). Downloading these resources, including seeing if they have changed using traditional HTTP caching, can affect the performance of using the editor, especially on latent connections.

Instead, WordPress decided to download all of these resources into a Gears LocalServer. The Gears LocalServer makes it possible to version a bundle of resources, such as JavaScript, CSS, etc. and grab them in one shot. Once files have been stored in the Gears LocalServer they are served up locally and immediately, blitting to the screen right when the page is first hit.

A common question is how this is different than standard HTTP caching. Standard HTTP caching can only version individual resources, and must do validity checks on every resource at regular intervals which can affect page load time. The Gears LocalServer instead versions an entire bundle, efficiently checking that resources have changed only if the version on the bundle itself has changed. Another major difference is that Gears always serves the resources first, then revalidates the bundle. In traditional HTTP caching, you have to either choose between choosing some date far in the future to revalidate at, or revalidating before serving.

Cache Data and Use Search Locally

A great next step is to use the Gears’ Full Text Search capabilities to give your users very fast local search. This can be used in conjunction with the Gears Database module to cache commonly used data for faster display and retrieval.

MySpace does this with their MySpace Mail feature. They download all of a users messages in the background using a Gears WorkerPool, index them into the Database for quick retrieval, and then drop a search form on to the page. As a user types the local database is queried in real-time, with the results shown instantaneously on the page without the latency of a round-trip server call.

You can also use the local database to cache commonly used data, such as zip code lookup tables or employee contact information. For example, MySpace uses this to provide fast, client-side sorts. A user can click the sort icon while viewing messages to sort by read/unread, date sent, sender, etc. Rather than having to return to the server, affecting performance, the sort happens very fast on the client-side using SQL against the local database.

YUI 2: Rich Text Editor

YUI 2: Rich Text Editor

The Rich Text Editor interface with the default YUI Sam Skin applied.The Rich Text Editor is a UI control that replaces a standard HTML textarea; it allows for the rich formatting of text content, including common structural treatments like lists, formatting treatments like bold and italic text, and drag-and-drop inclusion and sizing of images. The Rich Text Editor’s toolbar is extensible via a plugin architecture so that advanced implementations can achieve a high degree of customization.

In order to give you the greatest possible control over the size and performance of the Rich Text Editor codebase, we provide two versions of the Editor module and two versions of the buttons that live on the Toolbar:

* Editor: Editor contains all features described on this page;
* SimpleEditor: SimpleEditor contains a subset of Editor’s features. (See “Choosing Between Editor and SimpleEditor” for more details.)
* ToolbarButtonAdvanced: The advanced Toolbar buttons are based on YUI Buttons; they are more richly featured at the cost of more dependencies.
* ToolbarButton: The more simple Toolbar buttons have fewer dependencies and so are lighter on the page; they do not support progressive enhancement nor menu-button functionality. (See “Changing the Toolbar” for more about your Toolbar choices.)

Choose the right combination of features in your Editor and Toolbar to get the right tradeoff between size and richness for your application.

GMail File Storage

GMail Drive

by: viksoe.dk

GMail Drive is a Shell Namespace Extension that creates a virtual filesystem around your Google Mail account, allowing you to use Gmail as a storage medium.

GMail Drive creates a virtual filesystem on top of your Google Gmail account and enables you to save and retrieve files stored on your Gmail account directly from inside Windows Explorer. GMail Drive literally adds a new drive to your computer under the My Computer folder, where you can create new folders, copy and drag’n'drop files to.

Ever since Google started to offer users a Gmail e-mail account, which includes storage space of 6000 megabytes, you have had plenty of storage space but not a lot to fill it up with. With GMail Drive you can easily copy files to your Google Mail Account and retrieve them again.
When you create a new file using GMail Drive, it generates an e-mail and posts it to your account. The e-mail appears in your normal Inbox folder, and the file is attached as an e-mail attachment. GMail Drive periodically checks your mail account (using the Gmail search function) to see if new files have arrived and to rebuild the directory structures. But basically GMail Drive acts as any other hard-drive installed on your computer.
You can copy files to and from the GMail Drive folder simply by using drag’n'drop like you’re used to with the normal Explorer folders.

Because the Gmail files will clutter up your Inbox folder, you may wish to create a filter in Gmail to automatically move the files (prefixed with the GMAILFS letters in the subject) to your archived mail folder.

Please note that GMail Drive is still an experimental tool. There’s still a number of limitations of the file-system (such as total filename size must be less than 65 characters). Since the tool hooks up with the free Gmail Service provided by Google, changes in the Gmail system may break the tool’s ability to function. I cannot guarantee that files stored in this manner will be accessible in the future.

Yahoo! UI Library: YAHOO.util.Anim

Class YAHOO.util.Anim

Known Subclasses:
YAHOO.util.ColorAnim

Base animation class that provides the interface for building animated effects.Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);

Constructor

YAHOO.util.Anim ( el , attributes , duration , method )

Parameters:
el <String | HTMLElement> Reference to the element that will be animated
attributes <Object> The attribute(s) to be animated. Each attribute is an object with at minimum a “to” or “by” member defined. Additional optional members are “from” (defaults to current value), “units” (defaults to “px”). All attribute names use camelCase.
duration <Number> (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
method <Function> (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)

Properties

_onCompleteprivate object

Custom event that fires after onComplete

_onStartprivate object

Custom event that fires after onStart, useful in subclassing

_onTweenprivate object

Custom event that fires after onTween

actualFramesprivate Int

The number of frames this animation was able to execute.

attributesObject

The collection of attributes to be animated. Each attribute must have at least a “to” or “by” defined in order to animate. If “to” is supplied, the animation will end with the attribute at that value. If “by” is supplied, the animation will end at that value plus its starting value. If both are supplied, “to” is used, and “by” is ignored. Optional additional member include “from” (the value the attribute should start animating from, defaults to current value), and “unit” (the units to apply to the values).

currentFrameInt

The location of the current animation on the timeline. In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.

durationNumber

The length of the animation. Defaults to “1″ (second).

elprivate HTMLElement

The element to be animated.

isAnimatedprivate Boolean

Whether or not the animation is running.

methodFunction

The method that will provide values to the attribute(s) during the animation. Defaults to “YAHOO.util.Easing.easeNone”.

startTimeprivate Date

A Date object that is created when the animation begins.

totalFramesInt

The total number of frames to be executed. In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.

useSecondsBoolean

Whether or not the duration should be treated as seconds. Defaults to true.

Methods

animate

void animate ( )

Starts the animation by registering it with the animation manager.
Returns: void

doMethod

Number doMethod ( attr , start , end )

Returns the value computed by the animation’s “method”.
Parameters:
attr <String> The name of the attribute.
start <Number> The value this attribute should start from for this animation.
end <Number> The value this attribute should end at for this animation.
Returns: Number
The Value to be applied to the attribute.

getAttribute

Number getAttribute ( attr )

Returns current value of the attribute.
Parameters:
attr <String> The name of the attribute.
Returns: Number
val The current value of the attribute.

getDefaultUnit

String getDefaultUnit ( attr )

Returns the unit to use when none is supplied.
Parameters:
attr <attr> The name of the attribute.
Returns: String
The default unit to be used.

getEl

HTMLElement getEl ( )

Returns a reference to the animated element.
Returns: HTMLElement

getStartTime

Date getStartTime ( )

Returns the animation start time.
Returns: Date
current value of startTime.

init

void init ( el , attributes , duration , method )

Constructor for Anim instance.
Parameters:
el <String | HTMLElement> Reference to the element that will be animated
attributes <Object> The attribute(s) to be animated. Each attribute is an object with at minimum a “to” or “by” member defined. Additional optional members are “from” (defaults to current value), “units” (defaults to “px”). All attribute names use camelCase.
duration <Number> (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
method <Function> (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
Returns: void

isAnimated

Boolean isAnimated ( )

Checks whether the element is currently animated.
Returns: Boolean
current value of isAnimated.

onTween

private void onTween ( )

Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
Returns: void

setAttribute

void setAttribute ( attr , val , unit )

Applies a value to an attribute.
Parameters:
attr <String> The name of the attribute.
val <Number> The value to be applied to the attribute.
unit <String> The unit (‘px’, ‘%’, etc.) of the value.
Returns: void

setEl

void setEl ( )

Changes the animated element
Returns: void

setRuntimeAttribute

private void setRuntimeAttribute ( attr )

Sets the actual values to be used during the animation. Should only be needed for subclass use.
Parameters:
attr <Object> The attribute object
Returns: void

stop

void stop ( finish )

Stops the animation. Normally called by AnimMgr when animation completes.
Parameters:
finish <Boolean> (optional) If true, animation will jump to final frame.
Returns: void

toString

String toString ( )

Provides a readable name for the Anim instance.
Returns: String

Events

onComplete

onComplete ( )

Custom event that fires when animation ends Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)

onStart

onStart ( )

Custom event that fires when animation begins Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)

onTween

onTween ( )

Custom event that fires between each frame Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)