Graded Browser Support Update: Q3 2009

July 2, 2009 at 10:04 am by Eric Miraglia | In Development | 11 Comments

This post announces an update to Graded Browser Support. The GBS page on the YUI site always has the most current information. This post includes a list of changes, the updated chart of browsers that receive A-grade support, and our GBS forecast. The discussion section breaks out some of the strategy behind the current GBS update.

GBS Changes for Q3 2009

This GBS update adds A-grade support for Firefox 3.5 and for Safari 4.0. A-grade support is discontinued for Firefox 2, Opera on Mac OS X, and IE6 on Windows 2000. With this update, Windows 2000 drops from the A-Grade testing matrix and the testing surface is reduced to 14 browsers on 4 OS platforms (down from 15 browsers on 5 platforms).

  • Initiated A-grade support for Firefox 3.5, Windows XP
  • Initiated A-grade support for Firefox 3.5, Windows Vista
  • Initiated A-grade support for Safari 4.0, Mac OS 10.4
  • Initiated A-grade support for Safari 4.0, Mac OS 10.5
  • Discontinued A-grade support for IE6, Windows 2000
  • Discontinued A-grade support for Firefox 3.0, Windows Vista
  • Discontinued A-grade support for Firefox 2.0, Mac OS 10.5
  • Discontinued A-grade support for Firefox 2.0, Windows XP
  • Discontinued A-grade support for Opera 9.6, Mac OS 10.5
Win XP Win Vista Mac 10.4.† Mac 10.5.†
Firefox 3.0.† A-grade A-grade
Firefox 3.5.† A-grade A-grade A-grade
Opera 9.6.† A-grade
IE 8.0 A-grade A-grade
IE 7.0 A-grade A-grade
IE 6.0 A-grade
Safari 3.2.† A-grade
Safari 4.0. A-grade A-grade

Notes:

  • 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.

GBS Forecast

We expect to make the following changes in the Q4 2009 GBS update:

  • Discontinue A-grade support for Firefox 3.0.x across all OSs.
  • Discontinue A-grade support for Safari 3.2.x on Mac OS 10.5.
  • Begin publication of A-grade matrix for smartphones
  • Re-evaluate status of Google Chrome

Discussion

  1. Opera's marketshare in eastern Europe.Opera: Opera continues to be an important independent browser manufacturer, but its sub-1% global marketshare is now superseded by other browsers whose user base is growing more rapidly (including Safari on Apple’s iPhone OS and Google’s Chrome on Windows). In many ways, the X-grade browser class, which is full of excellent small-marketshare browsers, is the right category for Opera at this point. However, for developers of global products, Opera’s strong position in Russia and eastern Europe (source: StatCounter) argues persuasively for its continued inclusion in the A-grade. Hence, our advice remains that you continue to test your applications in the latest version of Opera on Windows XP. We’ve dropped A-grade support for Opera on Mac OS 10.x to reduce the testing surface and accommodate future inclusion of browsers with rapidly growing marketshare.
  2. Chrome: One of the most common questions we get about GBS today is: "What about Google Chrome?" It’s a fair question. Chrome is an excellent, innovative browser that adheres to web standards, and it has a rapidly expanding marketshare. Chrome remains an X-grade browser today because its marketshare is still very small on a relative basis. If Chrome maintains its current marketshare growth, it will be reclassified as A-grade within one or two quarters. Note that Google’s developer page for Chrome suggests that "if you’ve tested your website with Safari 3.1 then your site should already work well on Google Chrome." This is good advice.
  3. Yahoo! Search running on the iPhone OS version of Safari.Safari on the iPhone OS: The OS that drives Apple’s iPhone and iPod Touch devices is another ascendant category of browser traffic. Is Safari for the iPhone OS an A-grade browser? Our answer: No, but that doesn’t mean you can ignore it in your product planning and testing. We regard the emerging class of full-featured browsers on handheld devices to be a category that requires its own GBS matrix. Such a matrix should include testing advice for browsers including Safari on iPhone as well as the browsers that ship with Google’s Android OS and Palm’s Pre OS. Treating these browsers as X-grade today is the right decision based on their marketshare — remember, X-grade browsers are expected to support current web standards and to perform well in browsing well developed sites. But the rapid growth of web traffic coming through these browsers, their unique form factors (much smaller screens), and their new interaction paradigms (including touch-screen gestures) argue for an intentional and sometimes differentiated approach to web-application design and implementation. While most content should "just work" and work well, these devices need to be considered at the product-design stage. Providing an "A-grade" experience for your application may not be a question of whether your app runs in the browser but whether your app’s usability on a small touchscreen retains its usability. With this in mind, we’ll begin delivering a smartphone GBS matrix beginning in Q4 2009.

We’d love to hear your take on these issues and others in the comments section.

The GBS Archive

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Enhancing YUI-based Applications With Audio

June 30, 2009 at 8:41 am by Scott Schiller | In Development | 2 Comments

Scott SchillerAboot the author: Scott Schiller (@schill) is a front-end engineer on Flickr who joined Yahoo! in 2005, hailing from Canada. SoundManager 2 is one of his personal side-projects. As Flickr’s self-professed resident DJ, he can be seen playing at the occasional Web 2.0 party between tinkering with time-lapse videos and photographing things for sharing online. Scott’s experimental DHTML site is updated sporadically. In this article, Scott shows you how to use SoundManager to tie sound effects to specific user actions or events in YUI.

Sound is one of the major senses and a major part of daily life, and yet is largely ignored on the web. Web developers know that when it comes to HTML, audio is not as easy to add to a web site as it should be. Why is that? The following are some thoughts on the historical problems with embedding sound, a few ideas and some demos of embedding and controlling sound from Javascript with YUI.

Demos

If you’re like me, you’re probably wanting to see some fun stuff up-front because reading is work, and work is boring! ;) Feel free to play with the demos first and then read on for the details.

A Brief History of HTML and “Multimedia”

The web is pretty good at visual presentation. It is easy to create, design and embed images, text, and links in HTML documents. Of the media formats natively supported today in HTML 4, audio and video – or rather, <audio> and <video> – are conspicuously missing.

HTML 5 should bring audio and video embedding closer to the simplicity of <img /> in the not-so-distant future. In the meantime, we have to resort to creative work-arounds to get HTML-5-like audio/video functionality across the gamut of today’s common HTML 4-supporting browsers.

The (HTML 4) Problem With Embedding Audio

For audio on web sites today, developers often display a list of HTML links directly to MP3 files. This method is simple, universally-understood and indexable by search engines, but makes for a confusing and inconsistent browsing experience by default.

Users are generally prompted to right-click, “save as” and finally open the file from their desktop, or click the link and have their browser download and open the MP3 file. The regular “click” typically opens in a new page with the embedded player or launches an external application like QuickTime or Windows Media Player.

Not only are “naked” MP3 links extra work and confusing for the user, the browser’s method of handling them is a distraction and takes them away from the experience of your site.

Using <object>/<embed> is another generic way to directly embed MP3 or other content, but again suffers from the problem of inconsistency; the developer won’t know what may show in that area of the web page, given the user could have any array of applications which may load in order to handle that file type – in this case, likely the same QuickTime or Windows Media Player which would handle direct downloads would be shown in-place in your page. Again, not a great solution.

Flash widgets are sometimes used as a solution for embedding MP3 content, but the UI and skins tend to be 100% Flash-based rather than HTML and CSS-based and thus are more difficult for most web developers to customize. HTML 5 should change this with standards-based, CSS-skinnable and scriptable audio/video elements.

In the meantime, some creative solutions can be used to get more “web developer-friendly” widgets for audio.

Making MP3 Links “Just Work”: YUI + SoundManager 2

To have “progressively-enhanced” links to MP3s that will play in-place when clicked, something must intercept the browser’s normal download action and subsequently handle the request; by combining Javascript and Flash to handle the loading and playing of MP3 content, this can be done very effectively.

In a personal quest to get cross-browser audio control for a DHTML game back in 2002, I developed a JS + Flash audio API called SoundManager. Having since evolved to include video, SoundManager 2 implements and extends Flash’s native sound API and exposes it to Javascript. The result is cross-browser/platform scripted audio functionality which can help to bridge the gap for JS-driven sound until HTML 5 is widely supported.

By combining SoundManager 2 with YUI’s DOM and Event utilities, you have an effective solution for embedding and controlling audio which can gracefully degrade to a browser download or embedded player.

Practical Example: Playable MP3 Links

The following demo uses YUI and SoundManager 2 to enhance MP3 links, making them playable inline. YUI’s event utilities intercept clicks on links pointing to MP3 files and then use the SoundManager API to load and play the relevant URL before returning “false”, and preventing the browser from loading the link. Subsequent clicks will toggle play/pause state.

In the event Javascript/Flash aren’t present or if anything else goes wrong, the browser will simply fall through and load the MP3 link as usual.

Adding Audio To Your UI

Javascript-based animation, transition and motion effects add fluidity to web interface design and are becoming more commonplace. Smartly-applied audio can complement and further enhance the UI, making the experience more meaningful.

In certain applications, sound in the form of UI feedback can be appropriate and helpful to the user experience. Sound effects are common for Flash-based sites and web-based games, and in desktop gaming audio is usually a key part of telling the story.

.. But Don’t Over-Do It

It’s important to know when to stop. Recall animated “under construction” .GIFs? How about the blink tag? Marquee text? Some things are best left alone. Not every HTML page needs to move, blink, slide, flash and be noisy at the same time; even “fun” is best applied in moderation. Annoying your users with auto-playing music or noise can quickly lead to abandonment of your site.

There is probably good reason that standard HTML elements such as form controls and the like do not have sound effects or notifications associated with them. Perhaps “silence is golden” and it’s best that the web be a quiet place by default, so as not to be annoying and distracting.

As one notable exception to the “silent web” theme, Internet Explorer usually makes a “click” sound when page navigation occurs, presumably to notify the user that an action has started. This has become more muted in recent times, but is still present and still seems to annoy some users to this day.

“Fun” Example: A Noisy DOM

Despite the arguments for silence, the following is an example of what it might be like to have “noisy” form elements, buttons and DOM elements which provide audible feedback as they’re being used. The novelty is certainly to wear off quickly, but it does add an element of childish fun to the UI.

Looking Forward: HTML 5

Native <audio> and <video> support will mean it will be much easier to embed and control more media formats within the browser without relying on third-party plugins. Furthermore, an extensive Javascript API should encourage developers to create increasingly-innovative experiences.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

YUI 3.0.0 beta 1 Available for Download

June 24, 2009 at 2:35 pm by Eric Miraglia | In Development | 18 Comments

YUI 3.0.0 beta 1 is now available for download from YUILibrary.com.

This release takes YUI 3 out of its preview phase and brings its APIs to a near-final state. For those intending to implement YUI 3, the 3.0.0 beta 1 release is a good place to begin the transition. If you’ve been working with the latest preview release, George Puckett has provided a comprehensive 3.0.0 beta 1 changelog to guide you. We look forward to hearing your feedback as you begin working with 3.0.0 beta 1, and we’ll work hard to address that feedback as we prepare for a GA release in the coming months.

We’ve spent a lot of time in this release cycle refining the core elements of YUI 3 — YUI, Node, and Event — to ensure that we have the right API going forward. Performance is improved, and we’ve refined our module/submodule structure. In some cases we’ve added significant new features, including intrinsic support for event delegation in the Event package; however, the focus is on moving the base library to production quality.

Several YUI 2.x components make their YUI 3 debut in this release:

  1. DataSource: YUI’s data abstraction layer provides a standard interface into data sets, regardless of the data’s origin (local, XHR, XSS, etc.) and format (JSON, XML, CSV, etc.);
  2. ImageLoader: ImageLoader allows you to defer the loading of images that aren’t in the viewport when the page paints, throttling bandwidth usage and improving performance;
  3. History: The History component gives you control of the brower’s back button within the context of a single-page web application;
  4. StyleSheet: StyleSheet makes it easy to create and modify CSS rules on the fly, allowing you to dynamically style page elements with fewer repaints.

As part of the more granular packaging in the new codeline, we’ve created separate YUI 3 modules to house functionality that in YUI 2 was bundled with other components. Cache, DataType and DataSchema debut in this release; each of these used to be a part of DataSource.

Getting to Know YUI 3

The best way to get started with YUI 3 is to dive into the documentation and examples — particularly the examples for the core YUI, Node and Event components.

We also recommend spending some time with Satyen Desai, whose tech talk on YUI 3’s design goals and architecture provides an excellent overview of the new codeline. The video is embedded below; an HD version, along with a transcript, is available from the YUI Theater site.


Satyen Desai: "YUI 3: Design Goals and Architecture" @ Yahoo! Video

CSS Grids and YUI 3

Those of you who use the YUI CSS components may notice that we’ve removed references to YUI CSS Grids in the 3.0.0 beta 1 documentation, although Grids remains present in the download (and, of course, you can continue using the YUI 2.7.0 version of Grids).

We’ve deprecated the Grids implementation that was included in the preview releases, and we expect to significantly re-engineer this component before reintroducing it as part of YUI 3.

Roadmap

The 3.0.0 beta 1 release is an important milestone for YUI. At this point, we are encouraging all YUI implementers to use YUI 3 for new projects, especially projects that don’t make heavy use of widgets.

Our attention now turns to bringing YUI 3 to GA status. We expect this to happen in Q3, at which time the following components will be promoted to GA:

  • Core: YUI, Node, Event
  • Component foundation: Attribute, Base, Plugin
  • Utilities: Animation, Cookie, Drag and Drop, Get, History, ImageLoader, IO, JSON, Queue, StyleSheet
  • CSS: Reset, Base, Fonts

After 3.0.0 GA, the next major release will be 3.1.0, currently scheduled for Q4. The 3.1.0 release will bring the widget foundation to GA, including the following components:

  • Widget foundation: Widget and Widget extensions
  • Utilities: DataSource, DataSchema, DataType, Cache

During the 3.1.0 release cycle, we’ll also begin introducing specific widgets built upon the YUI 3 codeline. Note that Widget, its extensions, and the sample widgets shipping with 3.0.0 beta 1 are expected to evolve significantly in the coming months as we begin focusing more attention on that part of the library.

For full details on the roadmap, refer to the YUI 3.x Roadmap on YUILibrary.com. That page is kept current with the latest information about our plans and progress. The YUI 3.x Dashboard is also a useful resource for those wanting to track our progress toward major YUI 3 releases.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Flash SOL: Persistent Data with Local SharedObjects

June 23, 2009 at 1:05 pm by Alaric Cole | In Development | 4 Comments
Alaric Cole, Yahoo! Flash Platform Engineer

About the Author: Alaric Cole has been working in Flash since the advent of ActionScript and is currently a developer on Yahoo!’s Flash Platform team. You could say he’s grown with the language. Sure, he’s had his hand in independent film. Yeah, he wrote that one book. But his weekday ritual is still fooling about with Flash.

When he’s not crouched over a computer, you might find him riding brakeless in the Mission.

I’ve been working with Matt Snider of Mint.com to develop a new local storage utility for YUI. The utility will use a cascading storage system to detect the best way to store information through the browser, allowing a developer to store data more efficiently than a typical browser cookie — and in greater amounts. One of the storage mechanisms employs the Adobe Flash Player, and this use case has been the focus of my recent work.

Flash has a built-in persistent storage system called SharedObjects, which can be thought of as “super-cookies”, allowing the developer to store, by default, 100kb — or more, if the user allows. One of the benefits of SharedObjects, besides their capacity, is that they can store core ActionScript types, and even entire custom classes, in a binary format on the user’s hard drive. SharedObjects use the ActionScript Message Format (AMF), making them efficient and compact.

These SharedObjects are not encrypted, so while difficult to read, they are not what you would call secure storage. We’d never recommend storing important data such as user names, passwords, or other private data via a SharedObject unless you’ve implemented your own encryption mechanism. Also, SharedObjects are different from a cookie in more ways than capacity — SharedObjects are generally not attached to a specific browser but are stored independently.

These differences of the Flash storage system provide a number of benefits to the developer and the end user. However, while extremely convenient, they can also be misleading to the average user, many being unaware that such data even exists on their machine. While great lengths have been taken to provide transparency and control over private data to users via their browser (Firefox and Safari in particular providing a nice set of tools to view, edit, and remove cookies for various sites), the Flash storage system, due to its plugin nature, stores information in a separate location. This means that clearing your browser cookies does not clear these SharedObjects.

If you’re interested in viewing these bits of storage on your machine, you can check out the following locations:

Linux:

/.macromedia/Flash_Player/

Mac:

/Library/Preferences/Macromedia/Flash Player/

Windows:

/Application Data/Macromedia/Flash Player/

SharedObjects are typically stored in separate folders under these locations, in directories with such descriptive names as 8GKWKDQM and 227MDWL4. Under such folders are subdirectories corresponding to the domain in which the SharedObject came from.

The actual files have the *.sol extension, and there may be more than one for each domain. For instance, I found three separate SharedObject files on my machine under the youtube.com folder. They’re not human readable, as they are stored in binary.

When developing this storage utility, I wanted to be able to see the actual data stored in its raw form — but I didn’t have the time to parse through it all using a ByteArray, so I looked for a tool to do the job. I found a handy AIR application called Minerva, which can open a *.sol file and display its information. As of this writing, the current version doesn’t allow editing of the actual values stored, but there may be some other applications out there that I didn’t find.

Screenshot of Minerva application

If you’d like to remove some or all of these “Flash cookies”, you can simply delete the files or directories as needed. Note, however, that some sites make extensive use of SharedObjects, so removing them may cause unexpected behavior. Financial institutions in particular take advantage of them to aid in the security of their sites. So make sure you know what you’re doing, or create a backup before wreaking havoc.

An alternative to browsing through directories is to use Adobe’s Settings Manager. This is a Flash-based tool with special privileges that will allow you to view information about the storage on your machine, remove some or all of the stores, and set restrictions on future storage.

So, next time you want a clean slate for your browser, remember that there may be some additional information lurking on your machine that the browser can’t get to.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Coupling YUI and YQL to Build Dynamic Widgets

June 17, 2009 at 11:14 am by Jonathan LeBlanc | In Development | 8 Comments

Yahoo! Developer Network evangelist Jonathan LeBlancAbout the Author: Jonathan LeBlanc (twitter: jcleblanc) works with the partner integration group in the Yahoo! Developer Network as a senior software engineer / technology evangelist. Focusing on partner relationships and training, as well as external developer integration, Jonathan works with and promotes emerging technologies to aid in the adoption and utilization of new social development techniques. As a software engineer, Jonathan works extensively with social interaction development on the web, developing new methods for linking social networks to drive the ideal of an open web. Prior to Yahoo!, Jonathan worked within both the media production and fantasy product development teams at CBSSports.com, where he developed on products such as the Emmy award-winning march madness on demand video player. Born and raised in Canada, Jonathan graduated from Algonquin College of Applied Arts and Technology with a degree in computer science and currently lives in Dublin, CA with his wife.

YUI has a wonderfully rich list of data manipulation and UI utilities in its library, but coming up with equally rich and interesting data is generally your responsibility as an implementer. By the same token, YQL has rich data fetching and interaction abilities, but it lacks YUI’s visualization tools. Taking the visualization and control features of YUI and coupling them with the raw data pipe of YQL, we can build incredibly rich, interactive widgets without the need to create any of the visualizations or data storage mechanisms ourselves.

I’ll give you a tour of two widgets built with YUI and YQL in this post. One displays publicly available content and the other builds upon that original widget with a server-side PHP component to display private user data by authenticating with OAuth.

Accessing Public Data

Using the YUI Get Utility, we are able to make requests to the public YQL query URL without having the pain of dealing with the same-origin policy issue that would normally prevent us from making XHR-based requests to a server that is not on the same domain as the originating request. Below is a small code sample which showcases how you would call YQL using the YUI Get Utility:
<script type="text/javascript">
var getYQLData = function(query){
    //prepare the URL for the YUI GET request:
    var yqlPublicQueryURL = "http://query.yahooapis.com/v1/yql?";
    var sURL = yqlPublicQueryURL + "q=" + query
        + "&format=json&callback=yqlWidget.getYQLDataCallback";
        
    //make GET request to YQL with provided query
    var transactionObj = YAHOO.util.Get.script(sURL, {
        onSuccess : onYQLReqSuccess,
        onFailure : onYQLReqFailure,
        scope     : this
    });

    return transactionObj;
}
</script>

The query URL (sURL) is composed of several different parts to make up the request. The yqlPublicQueryURL variable contains the public URI for making requests to YQL. There are also three query parameters that we are passing along to this URI. The q parameter is the YQL query that we use in our request (e.g. select * from flickr.photos.search where text="YDN"), format is the format we want returned (JSON or XML) from the request, and if we want to wrap the JSON returned data in a function (a la JSONP) we can define a callback function using the callback parameter. When this function runs, the Get Utility will make a request to query.yahooapis.com with the specified query. On success, a debug message will be displayed in the onSuccess callback for the Get Utility then the callback defined in the YQL query will be called to parse the returned JSON results.

Setting up this widget on your own site or blog is as simple as downloading the code from the js-yql-display folder on github at http://github.com/jonleblanc/yql-utilities/tree/master and instantiating the widget like this:

<!-- widget file include -->
<script type="text/javascript" src="yql_js_widget.js"></script>

<!-- widget styles -->
<style>
div.imgCnt{ border: 1px solid rgb(96, 96, 96); 
    margin: 5px 5px 5px 0pt; float: left;
	background-color: rgb(241, 241, 241); width:100px;
	height:140px; }
div.imgCnt img{ border:0; margin:5px; }
div.imgCnt div.imgTitle{ padding: 5px; font-size: 11px;
    text-align:center; }
</style>

<script type="text/javascript">
var config = {'debug' : true};
var format = '<div class="imgCnt" align="center">'
    + '<a href="http://www.flickr.com/photos/{owner}/{id}/"'
    + 'target="_blank"><img src="http://farm3.static.'
    + 'flickr.com/{server}/{id}_{secret}.jpg?v=0"'
    + 'width="80" height="80" /></a>'
    + '<div class="imgTitle">'
    + '<a href="http://www.flickr.com/photos/{owner}/'
    + '{id}/">{title}</a>'
    + '</div></div>';
var yqlQuery =
    'select * from flickr.photos.search where text="YDN"';
var insertEl = 'widgetContainer';
yqlWidget.push(yqlQuery, config, format, insertEl);
</script>

Any number of public YQL queries can be made using the above example — all documentation for how the configuration script works can be found on github. If we run the above code we can easily display our most recent flickr photos:

flickr photo display

So, why all the fuss over using YQL and YUI together like this? Well, for me these utilities bring me quite close to a traditional MVC (Model View Controller) type of design pattern. YQL is a wonderful data aggregation and manipulation tool, but at the end of the day it’s just data. We insert the controller functionality using YUI utilities such as the Get Utility or Connection Manager, then we can build our presentation layer on top of that using widgets like DataTable and Charts.

private update stream

Accessing Private User Data

Let’s explore the pairing of YUI and YQL a little further by taking the foundation built in the public JavaScript query widget and attaching a server-side component to authenticate and store an oAuth session. Using the Y!OS PHP SDK, we are able to extend the JavaScript widget to display the update stream and personal badge details of the user who originally authenticated the widget. Since we’re using the PHP SDK on the same domain as our widget to make our authenticated calls to YQL, we no longer need to worry about the same-origin policy issues. This means that we can exchange the use of the YUI Get Utility with the YUI Connection Manager. The benefit to using the Connection Manager here is that we can use a standard ajax request and the event handlers of the utility instead of a callback within the YQL query. Our new request function would look something like this:

<script type="text/javascript">
var getYQLData = function(query){
    //prepare URL & post data for YUI Connection Manager POST:
    var sURL = "private_data_fetch.php";
    var postData = "q=" + query;

    //define Connection Manager event callbacks
    var callback = {
        success:parseYQLResults,
        failure:onYQLReqFailure
    };
		
    //make POST request to YQL with provided query
    var transactionObj = YAHOO.util.Connect.asyncRequest('POST',
	    sURL, callback, postData);
		
    return transactionObj;
}
</script>

The Connection Manager is used to make AJAX requests to the PHP SDK (whose references are housed in private_data_fetch.php within the above code) with the query as a POST parameter. The SDK in turn makes an authenticated request for the user’s personal data and dumps out a JSON string as the return of the request. Then all you need to do is parse the JSON string using the YUI JSON Utility; after you’ve called YAHOO.util.JSON.parse() on the transaction results, your data can be treated in the same manner as the data in the first example.

Since YQL generates results when the request is called, there is no need to house this data for yourself. YQL can pull data from any available source so you can build widgets such as these to display dynamic results with each refresh.

Both of the widgets showcased in this post are freely available for download and contribution on github at http://github.com/jonleblanc/yql-utilities/tree/master. These widgets are:

  • js-yql-display: JavaScript widget to display public YQL data
  • php-yql-display: JavaScript / PHP widget to display private YQL data

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Draggable DataTable Rows

May 8, 2009 at 2:50 pm by Gonzalo Cordero | In Development | 1 Comment

About the Author: Gonzalo Cordero is a Front-End Engineer on the Yahoo! Flex Force team. He is currently working on the next generation of Yahoo! homepage. He is also a former Juku graduate, where he recently became an instructor as well. In this article he walks us through the process of adding Drag and Drop functionality to a DataTable widget.

Introduction

A recent project of mine required an implementation of DataTable where rows could be moved around with Drag and Drop functionality. After looking through the YUI gallery of examples, I realized that the feature I was trying to implement was a little bit different from the ones I saw. So I decided to implement my own solution. In this article I’ll explain how I combined YUI’s DataTable and Drag and Drop components, some workarounds for the challenges I encountered, and how I was able to improve upon my initial solution by using the new YUI3 codeline (which is currently available in preview mode).

Screenshot of draggable DataTable rows.

Initial considerations and some possible solutions

The first question that came to my mind was how to make each table row draggable and a drop target at the same time in the most efficient way. I also knew that instantiating a Drag and DDTarget object at the same time on an element wasn’t going to work. After reading through the Drag and Drop API documentation I found out that the property isTarget gets set by default to true for every Drag object we create, making that object a drop target as well. So with that, I defined a custom DDRows class to set up the interesting moment handlers and also add some CSS style for the drag proxy object to visually differentiate it from the regular rows. A proxy drag object is just a container that gets displayed once the dragging starts and it serves as a marker/guide for what is being dragged.

YAHOO.example.DDRows = function(id, sGroup, config) {
    YAHOO.example.DDRows.superclass.constructor.call(this, id, sGroup, config);
    Dom.addClass(this.getDragEl(),"type-proxydrag");
};

YAHOO.extend(YAHOO.example.DDRows, YAHOO.util.DDProxy, {
	// Handlers defined here
});

After defining the DDRows class, I listen for the DataTable’s initEvent to set up each row as a DDRows Drag object:

myDataTable.subscribe("initEvent", function() {
    var i, id,
    allRows = this.getTbodyEl().rows;

    for(i=0; i<allRows.length; i++) {
        id = allRows[i].id;

        // Clean up any existing Drag instances
        if (myDTDrags[id]) {
            myDTDrags[id].unreg();
            delete myDTDrags[id];
        }

        // Create a Drag instance for each row
        myDTDrags[id] = new YAHOO.example.DDRows(id);
    }
});

Then instead of using the DDTarget class, I look for the isTarget property of the Drag object to validate the target element. This way we make sure we only move table rows onto other table rows:

onDragDrop: function(e, id) {
    var destDD = YAHOO.util.DragDropMgr.getDDById(id);
    // Only if dropping on a valid target
    if(destDD && destDD.isTarget && this.srcEl) {
            ...
    }
}

An important consideration is that the DOM is repainted each time we move a row, so not only does the Drag object on the original row need to be cleaned up when it is deleted, a new Drag object needs to be created for the row that is created in the new position. Here is the entire onDragDrop function that cleans up and moves a row:

onDragDrop: function(e, id) {
    var destDD = YAHOO.util.DragDropMgr.getDDById(id);
    // Only if dropping on a valid target
    if(destDD && destDD.isTarget && this.srcEl) {
        var	srcEl = this.srcEl,
            srcIndex = srcEl.sectionRowIndex,
        	destEl = Dom.get(id),
        	destIndex = destEl.sectionRowIndex,
            srcData = myDataTable.getRecord(srcEl).getData();

        this.srcEl = null;

        // Cleanup existing Drag instance
        myDTDrags[srcEl.id].unreg();
        delete myDTDrags[srcEl.id];

        // Move the row to its new position
    	myDataTable.deleteRow(srcIndex);
        myDataTable.addRow(srcData, destIndex);
    	YAHOO.util.DragDropMgr.refreshCache();
    }
    }
}

Here is the full working example using YUI 2.7.0.

Enhancing our example by using YUI 3.0 PR2

On the Yahoo! homepage, we have been using YUI 3 to develop our next-generation experience, and the more I use it, the more I realize how powerful and extensible it is. So I decided to go ahead and check out the Drag and Drop component from the latest YUI 3.0 preview release for this exercise.

It was no surprise when I discovered that with this new version I could take advantage of some of the new properties and methods to make my solution more clean and efficient. For instance, Drag and Drop in YUI 3 provides an efficient way to create the Drag/Target objects we need:

myDTDrags[id] =  new Y.DD.Drag({
    node: "#"+id,
    constrain2node: "#datatable",
    moveOnEnd: false,
    proxy: true,
    target: true
});

We no longer have to define our own subclass or worry about validating the element before swapping rows, as the drophit event will only be triggered when applied to elements we’ve defined as drop targets.

The other great new feature version 3 brings us is custom-event bubbling (which brings the power of DOM-event bubbling to the custom events that drive the library’s API). Thanks to this, we can now to listen for all the Drag and Drop events at the document level using the Drag and Drop Manager, rather than having to attach several events to each individual table row. Our custom-event delegation code looks like this:

Y.DD.DDM.on('drag:start',startDrag);
Y.DD.DDM.on('drag:end',endDrag);
Y.DD.DDM.on('drag:drophit',dragDrop);

Here is the full working example using YUI 3.0 PR2.

Conclusion

I hope you find these examples a useful resource on how to add Drag and Drop functionality to DataTables and on how you easily you can integrate YUI 2.7.0 and YUI 3 components in the same page. It also serves as a quick preview on all the new and exciting features that are coming with the next generation of YUI.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

YUI 2.7.0 on TaskSpeed

April 13, 2009 at 2:21 pm by Luke Smith | In Development | 9 Comments

Screenshot of TaskSpeed

A few months ago Peter Higgins, a contributor to the Dojo Toolkit, adapted the SlickSpeed test framework to do higher level comparisons of how various JavaScript libraries perform when doing some “common” DHTML tasks. The new test framework is called TaskSpeed. And thanks to the excellent work done by one of our favorite community members, Eric Ferraiuolo, YUI 2.7.0 now has representation in the matrix as well.

About TaskSpeed

Whereas SlickSpeed compares the performance of the respective JavaScript CSS selector engines in common libraries, TaskSpeed attempts to qualify a larger set of library functionality with less granularity. The goal seems to be to predict what a library consumer might expect for aggregate speeds when developing on top of library A vs. library B.

In addition to each of the participating libraries, a “PureDom” column represents the performance of the given task with plain old JavaScript and direct DOM interaction, serving as a healthy reminder that the benefits you get from using a JavaScript library don’t come for free. Unfortunately, “PureDom” might also be incorrectly construed as an argument in favor of not using a library at all, but that is a separate and lengthy discussion.

The results

Though YUI 2.7.0 was only added to the matrix on April 10th, the results submitted so far suggest that YUI performs the given tasks with comparable efficiency in the newer browsers, and better than most in Internet Explorer 6, 7, and 8.

IE 8 results from Apr 10 – Apr 13

Chart of IE8 performance comparisons

Take-aways

Though YUI performs ably, it’s my opinion that the numbers seen in TaskSpeed should be taken with a hefty grain of salt. The tests are designed to exercise library abstraction logic against DOM-intensive operations. The issue here is twofold:

  1. Not all libraries (YUI included) have abstraction logic for all of the specific tasks, which breaks the apples-to-apples comparison.
  2. And in order to get meaningful numbers, the test operations are iterated up to 500 times or performed against excessive numbers of nodes. In real-world cases, these conditions are not the norm, meaning the differences are exaggerated, perhaps even grossly.

By and large, TaskSpeed may be more of a distraction than a source of information useful to the consumer. My greatest concern is that people will make a decision to choose one library over another based on which one can add a ridiculous number of event subscribers in 25 milliseconds vs. 30, ignoring more important issues like cross-browser stability, code maintainability, documentation quality, and community support.

This is not to say that TaskSpeed is without value. Here are the interesting take-aways I’ve found:

  1. Accounting for the lengthy iterations TaskSpeed needs to make the numbers substantial, all libraries perform common tasks pretty quickly.
  2. Libraries are getting faster, as seen by comparing version to version of the same library where available.
  3. There is a performance price to pay for the stability and consistency any library offers.
  4. For the library authors and contributors, an apples-to-apples comparison of task execution can highlight potential areas where we may each be able to evolve to use best-of-breed techniques for everyone’s benefit!

I’d like to personally extend a big “thank you” to Eric Ferraiuolo for having done the fantastic legwork on this. Another great example of the importance of community contributions to the YUI library!

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Next Page »
Hosted by Yahoo!

Copyright © 2006-2009 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service

Powered by WordPress on Yahoo! Web Hosting.