• Home
  • Quick Start
    • Configurator
    • Download YUI 3
  • Documentation
    • User Guides
    • Examples
    • Tutorials
    • API Docs
  • Community
    • Gallery
    • Blog
    • Forums
    • YUI Theater
    • Calendar
  • Contribute
    • YUI on GitHub »
    • File a Ticket
    • View Tickets
    • Dashboard
  • Other Projects
    • YUI 2
    • YUI Compressor
    • YUI Doc »
    • YUI Builder
    • YUI PHP Loader
    • YUI Test
    • YUI Website

Blog: Archive for June, 2008

« Older Entries

Production JavaScript Debugging

You know the scenario. A bug is filed for a JavaScript issue
in production. You update your development server to the same files (allegedly)
that are in production but you can’t reproduce the issue. Debugging your
JavaScript code is horrifically difficult, if not impossible, because you’re
following best practices and crunching the file using the YUI Compressor.

You start by typing the URL of the JavaScript into a browser to confirm that the file is there. It is, and in fact, is being loaded into the browser without issue. So something must have gone wrong during the deployment process, but you need to know what part of the code is failing. Firebug, your trusty companion for JavaScript debugging, is essentially useless as it has a hard time deciphering all of your code from a single line.

When I end up in this situation, I turn to a little-known but incredibly powerful tool from Microsoft called Fiddler. Fiddler is an HTTP debugging proxy that filters all the requests coming to your machine via HTTP. It interfaces directly with WinINET, the Microsoft Internet communications stack, so it automatically picks up any requests and responses by programs using this library. By simply starting Fiddler, it will automatically pick up HTTP traffic for Internet Explorer, Safari, and Opera. Firefox doesn’t use WinINET, so you need to manually set it up to go through Fiddler. You can do so by going to the Tools menu and clicking on Options. Go to the Network tab and click the Settings button. Select Manual Proxy Configuration and enter localhost as your server and 8888 as your port. Click OK to apply the settings.

Setting up Firefox's options in preparation for using Fiddler.

Once that’s done, you’re ready to start debugging that production JavaScript. The key to debugging is really to create a readable version of the JavaScript so that Firebug (or any other JavaScript debugger) can be used to step through the code and set breakpoints as normal. To do so, download the file in production to your local machine. Use a pretty printing tool, such as Einars "elfz" Lielmanis’ online beautifier to create a more readable version of your code and save it to a local file. It’s important to follow this process instead of using your development version of the JavaScript to ensure that you’re using the exact same code that is on production; you can more easily rule out deployment issues this way.

The Fiddler Autoresponder tab.

Next, click on Fiddler’s AutoResponder tab. The settings on this tab allow you to intercept requests and respond as if you were the server. It’s possible to respond with a status code or with actual content. To enable this feature, check the Enable automatic responses checkbox. The Permit passthrough for unmatched requests checkbox should be checked by default, which is necessary to avoid interfering with other requests. Click the Add button to create a new entry. The textbox on the left should contain either the complete URI for the JavaScript file you want to intercept, or you can create a regular expression by preceding your text with "regex". The second textbox is for the response that should be sent. Click the dropdown arrow and select Find a file. Select the pretty-printed JavaScript file from your computer and click the Save button. This places your filter in Fiddler’s memory so the next time a file matching the given URI or description is requested, it will respond by sending back the file on your computer.

After that, you can navigate back to the production server on which the problem exists knowing that your file will be inserted in place of the actual production file. The browser itself is none the wiser that the file has been swapped out, so you’re safely able to debug readable code without making any changes to the code on the server. This technique has helped me debug some of the more complex issues I’ve dealt with at Yahoo!, and I hope that it can help you as well.

By Nicholas C. ZakasJune 27th, 2008

“AutoGrid” for YUI Grids — Using JavaScript to Create Adaptive Grids

I love YUI Grids. I know my CSS and I know how to work around different problems of browsers, but I am also very much bored about having to fix and test and create these workarounds over and over again. While YUI Grids might not be perfect for all cases of web development out there, I am happy to take a pragmatic approach and just create sites that can be done with them (now you also know why I am not a designer).

One problem I keep having when I put some YUI Grids-based sites live is that people complain about me expecting a certain screen resolution or viewport size. YUI grids can either be 100% wide, which can be pretty silly on high resolutions, or optimized for resolutions of either 800×600 or 1024×768. When you optimize for 800 pixels people on higher resolutions will complain about the length of the page and when you go for 1024 people will say they have to scroll to see your side-bar on 800×600. You can’t win.

Or can you? CSS is not dynamic — it has a fixed state and you can only hope that the browser does the right thing with what you give it (well, there are conditional comments for IE, but technically they are HTML, and of course there are media queries in CSS3 and other goodies, but for the sake of the argument let’s say supporting IE6 is a base). JavaScript, on the other hand, is very dynamic and you can read out and check what is happening to the browser currently in use and react to it.

Putting this feature of JavaScript to good use you can create a YUI-Grids-based layout that remains flexible and changes according to needs. All you need to do is use some YUI Dom magic and change IDs and classes accordingly.

YUI Grids come in several flavours of overall width, defined by the ID on the container DIV:

  • #doc – 750px centered (good for 800×600)
  • #doc2 – 950px centered (good for 1024×768)
  • #doc3 – 100% fluid (good for everybody)
  • #doc4 – 974px fluid (good for 1024×768)
  • #doc-custom – custom width

One thing to remember here is that even doc3 has a minimum width of 750 pixels, which is why for a fully flexible grid you need to override that:

#doc3{
  min-width:0;
}

Inside the container DIV you can have two blocks, and their width and the position of the side bar is defined by the class on the container DIV:

  • .yui-t1 – Two columns, narrow on left, 160px
  • .yui-t2 – Two columns, narrow on left, 180px
  • .yui-t3 – Two columns, narrow on left, 300px
  • .yui-t4 – Two columns, narrow on right, 180px
  • .yui-t5 – Two columns, narrow on right, 240px
  • .yui-t6 – Two columns, narrow on right, 300px

Putting these together you can create a plan for your flexible grid:

  • When the available screen space is larger than 950 pixels, use doc2 and the widest sidebar — either left or right
  • If you have less than 950 pixels, use doc and the medium size sidebars
  • If you have less than 760 pixels, use doc3 and the smallest sidebars
  • If you have even less — say 600 pixels — at your disposal, show the side bar below the main content

The script to allow for this is not really rocket science. All it needs to do is read out the grids settings, the width of the available browser window and then change the IDs and classes accordingly.

YAHOO.example.autoGrid = function(){
  var container = YAHOO.util.Dom.get('doc') || 
                  YAHOO.util.Dom.get('doc2') || 
                  YAHOO.util.Dom.get('doc4') || 
                  YAHOO.util.Dom.get('doc3') ||
                  YAHOO.util.Dom.get('doc-custom');
  if(container){
    var sidebar = null;
    var classes = container.className;
    if(classes.match(/yui-t[1-3]|yui-left/)){
       var sidebar = 'left';
    }
    if(classes.match(/yui-t[4-6]|yui-right/)){
       var sidebar = 'right';
    }
    function switchGrid(){
      var currentWidth = YAHOO.util.Dom.getViewportWidth();
      if(currentWidth > 950){
        container.id = 'doc2';
        if(sidebar){
          container.className = sidebar === 'left' ? 'yui-t3' : 'yui-t6';
        }
      }
      if(currentWidth < 950){
        container.id = 'doc';
        if(sidebar){
          container.className = sidebar === 'left' ? 'yui-t2' : 'yui-t5';
        }
      }
      if(currentWidth < 760){
        container.id = 'doc3';
        if(sidebar){
          container.className = sidebar === 'left' ? 'yui-t1' : 'yui-t4';
        }
      }
      if(currentWidth < 600){
        container.id = 'doc3';
        container.className = '';
      }
    };
    switchGrid();
    /* 
      Throttle by Nicholas Zakas to work around MSIE's resize nasties.

http://www.nczonline.net/blog/2007/11/30/the_throttle_function

    */
    function throttle(method, scope) {
      clearTimeout(method._tId);
        method._tId= setTimeout(function(){
        method.call(scope);
      }, 100);
    };
    YAHOO.util.Event.on(window,'resize',function(){
      throttle(YAHOO.example.autoGrid.switch,window);
    });
    
  };
  return {
    switch:switchGrid
  };
}();

Let's go through it step by step:

YAHOO.example.autoGrid = function(){
  var container = YAHOO.util.Dom.get('doc') || 
                  YAHOO.util.Dom.get('doc2') || 
                  YAHOO.util.Dom.get('doc4') || 
                  YAHOO.util.Dom.get('doc3') ||
                  YAHOO.util.Dom.get('doc-custom');
  if(container){

First we check if there is actually a YUI Grid in the current document, by testing for the presence of the correct IDs. If there is, we execute the rest of the code.

    var sidebar = null;
    var classes = container.className;
    if(classes.match(/yui-t[1-3]|yui-left/)){
       var sidebar = 'left';
    }
    if(classes.match(/yui-t[4-6]|yui-right/)){
       var sidebar = 'right';
    }

We define sidebar as null, retrieve the class name of the container element and check if there was a column structure defined. In addition to the preset YUI Grids classes we also defined yui-left and yui-right here. These styles allow you to not have a sidebar without the script functionality but to get one once the script determines that there is enough space for one.

    function switchGrid(){
      var currentWidth = YAHOO.util.Dom.getViewportWidth();
      if(currentWidth > 950){
        container.id = 'doc2';
        if(sidebar){
          container.className = sidebar === 'left' ? 'yui-t3' : 'yui-t6';
        }
      }
      if(currentWidth < 950){
        container.id = 'doc';
        if(sidebar){
          container.className = sidebar === 'left' ? 'yui-t2' : 'yui-t5';
        }
      }
      if(currentWidth < 760){
        container.id = 'doc3';
        if(sidebar){
          container.className = sidebar === 'left' ? 'yui-t1' : 'yui-t4';
        }
      }
      if(currentWidth < 600){
        container.id = 'doc3';
        container.className = '';
      }
    };
    switchGrid();

The method switchGrid() does all the work we defined. We set up the different cases for applying IDs and classes and call the method immediately after it's been defined.

    /* 
      Throttle by Nicholas Zakas to work around MSIE's resize nasties.

http://www.nczonline.net/blog/2007/11/30/the_throttle_function

    */
    function throttle(method, scope) {
      clearTimeout(method._tId);
        method._tId= setTimeout(function(){
        method.call(scope);
      }, 100);
    };
    YAHOO.util.Event.on(window,'resize',function(){
      throttle(YAHOO.example.autoGrid.switch,window);
    });

For full flexibility, we also apply an event listener that re-checks the grid specifications when the user resizes the browser. As Internet Explorer has a nasty habit of firing the resize event while the user resizes the window, we need to throttle the execution of switchGrid(). This is explained in detail on Nicholas Zakas' blog.

  };
  return {
    switch:switchGrid
  };
}();

As the throttle method needs a public method to call from setTimeout() we return a pointer to switchGrid.

That's all. You can try out the effect on the demonstration page. If you define your sidebar independent of size, you can create some wonderfully dynamic and flexible sites with this little script.

By Christian HeilmannJune 25th, 2008

Building Your Own Widget Library with YUI

The Yahoo! User Interface Library (YUI) has an ample assortment of
components. Nevertheless, there will be always some functionality you want that a library like YUI hasn’t anticipated or hasn’t built yet.
Sometimes you just want a subset of the many options a component might provide; in other cases, you may have a default configuration that you’d like to bake into a component to facilitate consistent use across your site. The flexibility built into YUI provides intrinsic support for extending, customizing, or creating wholly new components. If you find yourself in one of these situations, then building your own library of YUI-based components may make good sense.

This lengthy article is meant to get you started creating your own custom components using the tools available to you within YUI, including the Element Utility and the Event Utility. Understanding these tools can save you lots of time and make it easy to create API-driven components that expose powerful hooks to implementers making use of your work.

  • Customizing Existing YUI Components
    • Using YAHOO.lang.extend
    • Creating and Using Shortcuts for Common YUI References
    • Registering a Component with YUI
  • Developing Wholly New Widgets with YUI
  • The YUI Element Utility as a Foundation for Component Development
  • Managing DOM Events and Custom Events with Element
  • A Closer Look at extend
  • Element and AttributeProvider
  • Adding a render Method
  • Adding a Destructor
  • Subclasses
  • Bundling Functionality: The Field Object and the Fields Object
  • Progressive Enhancement
  • CSS Sprites
  • Final Thoughts
  • (more…)

    By SatyamJune 24th, 2008

    Image Transformations in Canvas with Slicing

    We’ve been obsessed with the canvas tag for a while now; we think it represents a huge opportunity for creative interfaces on the web, and current browser support for the tag is excellent (as long as you don’t mind using excanvas.js for IE6/7). That being said, there are some limitations. The only available built-in transformations are translation, rotationg and scale. Performing a complex transformation, such as keystoning an image so that it can be used in a faux 3D environment, has been difficult.

    However, there is an easy way to simulate arbitrary transformations on images in canvas. If you cut the image into slices, you can redraw each slice with different dimensions. The code is simple: using the slicing variation of the drawImage method, it’s possible to take a slice of a source image and draw it to the canvas. This slice can be scaled horizontally and vertically according to a formula. As the number of slices increases, the edges of the image become smoother and less jagged. It’s important to note that you only need one copy of the source image, and that drawing many slices doesn’t mean there are many copies of the image in the page. You are able to use one source image to draw multiple images on a destination canvas.

    Creating a keystone effect looks complex but is actually very straightforward:

    function keystoneAndDisplayImage(ctx, img, x, y, pixelWidth, 
    								 scalingFactor) {
    	var h = img.height,
    	     w = img.width,
            
    	    // The number of slices to draw.
    	    numSlices = Math.abs(pixelWidth),
            
    	    // The width of each source slice.
    	    sliceWidth = w / numSlices,
            
    	    // Whether to draw the slices in reverse order or not.
    	    polarity = (pixelWidth > 0) ? 1 : -1,
    
    	    // How much should we scale the width of the slice 
    	    // before drawing?
    	    widthScale = Math.abs(pixelWidth) / w,
            
    	    // How much should we scale the height of the slice 
    	    // before drawing? 
    	    heightScale = (1 - scalingFactor) / numSlices;
    
    	    for(var n = 0; n < numSlices; n++) {
    
    		// Source: where to take the slice from.
    		var sx = sliceWidth * n,
    		    sy = 0,
    		    sWidth = sliceWidth,
    		    sHeight = h;
    		
    		// Destination: where to draw the slice to 
    		// (the transformation happens here).
    		var dx = x + (sliceWidth * n * widthScale * polarity),
    		    dy = y + ((h * heightScale * n) / 2),
    		    dWidth = sliceWidth * widthScale,
    		    dHeight = h * (1 - (heightScale * n));
    
    		ctx.drawImage(img, sx, sy, sWidth, sHeight, 
            			  dx, dy, dWidth, dHeight);
    	}
    }
    

    We take slices from the source image one at a time, apply a horizontal and vertical transformation, and then draw it in the correct order. This also allows us to do something interesting; if the slices are drawn in reverse order, we can reverse the image. The keystone demo page shows this code in action. The two sliders control the values entered into the function as pixelWidth and scalingFactor. Keystoning has a lot of potential applications. For instance, If you animate both width and scaling, you can create a page turning effect for any image.

    You can apply any transformation to the slices. If you were to scale the height of the slices based on a parabolic curve, you could create a cylindrical distortion that mimics a panorama view. We set up a Quicktime VR-style panorama using this technique. Be sure to view it with the rest of the canvas both shown and hidden to see how it works. It would also be possible to add an animating flag-ripple effect to any image, just by varying dy. We believe that image slicing transformations have a lot of applications in mimicing 3D environments and creating image effects. All you have to do is apply a formula to change the slice dimensions or position.

    By Ross Harmes and Ernest DelgadoJune 23rd, 2008

    In the Wild for June 20

    It’s a toasty 105 degrees this evening in California — what better way to cool off (and celebrate the solstice) than to dive into the wild with some of the many YUI items that have caught our eye since the last post?

    • Nicora.net's YUI-based PhotoViewer Control.Nicora.net’s YUI PhotoViewer: Can you ever have too many lightbox options? Check out nicora.net’s YUI-based PhotoViewer Control, with a variety of flavors and built-in support for Flickr APIs.
    • Instant Shiny Forms with Rails and YUI: That’s the title of Enleitened’s new tutorial that "demonstrate[s] how to convert standalone Ruby on Rails forms to a YUI Dialog (hey, it’s one less page load) in only 4 easy steps."
    • Javascript Framework Usage Among the Top 100 Websites: Royal Pingdom started some interesting discussions a few weeks back with its article exploring which JS frameworks were in use at the top 100 websites (based on Alexa and Webware data). They found Prototype, JQuery and YUI leading the way among these top sites (excluding most of Yahoo!’s own mainstream properties, which all rely on YUI to some degree). The authors were quick to point out that theirs was not a scientific survey, but they noted their surprise at what the research turned up — and what it failed to turn up. (Note: YUI’s popular CSS components were discluded from this survey; Mint, which also uses YUI extensively, was acknowledged for its use of MooTools.)
    • Exploring YUI Custom Events: Speaking of Mint, Matt Snider is back with another YUI tutorial, this one using YUI Custom Events to create an "Object Subscription Pattern."
    • Using YUI CSS with Django: Over on Sofeng’s Blog, Sofeng noticed that The Django Book uses YUI CSS; he worked up a tutorial to show you how to do the same in your own Django project.
    • Learning YUI: Nathan Smith recently started work at one of my favorite alt-search-engines, Viewzi, which uses YUI. He picked up Dan Wellman’s book to learn the ropes, and then he posted a nice review of some of what he’s discovered as a new YUI user.
    • Adam Moore + Douglas Crockford = Epiphany: Lenny Burdette writes on his Rule52 blog about "How YUI’s event listeners changed the way I write JavaScript", bringing together insights from the sample chapter of Douglas Crockford’s JavaScript: The Good Parts and the expressive power of Adam Moore’s YUI Event Utility.
    • Richard Benson's YUI RTE plugin for Movable Type.Richard Benson’s YUI Rich Text Editor Plugin for Movable Type: In Richard’s words: "YUI has become my new favourite Rich Text Editor and I have been implementing it left right and centre. Its extensibility, features and ease of use are unparalleled. It made sense for all these features to be available to me in Movable Type so why not package it up into a plugin too? … Options include stretching the editor to fit the content automatically and disbaling use of the MT assets selection tools in favour of a simpler URL-based image chooser." Check out the plugin in the Movable Type Plugin Directory.
    • Adding Tabs to Your WordPress Blog: Adrian Diaconescu at Rubiqube went looking for a good tabbed-content solution for his WordPress sidebar, but he couldn’t find something that fully scratched the itch. His response was to deploy the YUI TabView Control, and he’s written up a detailed tutorial so you can leverage his work.
    • YUI DataTable in Grails: Marcel Overdijk recently whipped up a nice example integrating YUI DataTable in Grails.

    Did we miss something good? Probably so…if so, let us know in the comments.

    By Eric MiragliaJune 20th, 2008

    Video: Scott Davis on Using YUI with Grails

    Scott Davis talks about Groovy and Rails at the Rich Web Experience.

    Mastering Grails columnist (and author of books on topics ranging from Java to GIS) Scott Davis gave a fantastic talk on using YUI with Grails at the 2007 Rich Web Experience in San Jose. Thanks to Jay Zimmerman and his No Fluff Just Stuff conference team, that talk is now available freely on video from the RWE website.

    By Eric MiragliaJune 14th, 2008

    A Style All Their Own

    Modifying a DOM element’s style during user interaction is one of the
    pillars of creating DHTML interfaces that transition from state to state in a
    smooth, and (hopefully) intuitive way. Every HTMLElement in the DOM
    contains style, a collection of properties corresponding to the
    CSS properties understood by the browser. For JavaScript and CSS enabled browsers, the following two paragraphs would contain red text:

    <-- Paragraph 1 -->
    <p style="color: #f00">This paragraph is red</p>
    
    <-- Paragraph 2 -->
    <p id="x">This paragraph's color will be red after the JavaScript runs</p>
    <script type="text/javascript">
    (function () {
        var el = document.getElementById('x');
    
        el.style.color = '#f00';
    
    })();
    </script>
    

    Even CSS properties that aren’t applicable to a given element will have representation in that element’s style collection. For example, even the <br> element will have the el.style.letterSpacing property.

    Names have been changed to protect the innocent

    The style property names in JavaScript are camel cased versions of their CSS
    counterparts, so font-family in CSS becomes
    el.style.fontFamily in the style collection. "float" is a reserved word in
    JavaScript, so the CSS float property is given a different name. In Internet
    Explorer, styleFloat is used, where Firefox, Safari, and Opera all
    use cssFloat (Opera also supports styleFloat, actually). Additionally, each browser has a host of proprietary CSS properties that also show up in the style collection (e.g. -moz-border-radius, which becomes el.style.MozBorderRadius in Firefox). Other than styleFloat/cssFloat, the browser vendors largely agree on non-proprietary property names.

    The madness and the method

    I set out to document which properties were present in each A Grade browser’s style collection (making no claims about their functional support for specific values).

    For each browser, I used a simple for (var prop in el.style) method to iterate the style collection, and cross checked in a development tool if available. Specifically, I used the following:

    Browser Method
    Internet Explorer 6 for ( in ) and Visual Web Developer 2008 Express Edition
    Internet Explorer 7 for ( in ) and Visual Web Developer 2008 Express Edition
    Firefox 2.0.0.14 for ( in ) and FireBug 1.1
    Firefox 3 (Release Candidate 2) for ( in ) and FireBug 1.1
    Safari 3.1.1 (WebKit build 4525.18) Dom Inspector*
    Opera 9.27 for ( in )
    Opera 9.5 (beta and GA) for ( in ) and Opera Dragonfly

    * – Safari does not enumerate unassigned style properties, so for ( in ) doesn’t show anything useful.

    All tests were done on a Macbook Pro running OSX 10.4. The IEs and FF2 were tested on Parallels instances running Windows XP. I only documented properties that weren’t prefixed with a vendor identifier (e.g. -moz), and omitted methods and meta fields such as setProperty and length. The only exception to this being cssText, which I’ll talk more about later. So without further ado…

    Click through to see the full table of CSS properties.

    (more…)

    By Luke SmithJune 12th, 2008
    « Older Entries

    Pages

    • About
    • Contribute
    • YUI Jobs

    Recent Posts

    • YUI Weekly for May 17th, 2013
    • Yahoo’s International Team Is Hiring!
    • YUICompressor 2.4.8 Released
    • YUI 3.10.1 Released to Fix SWF Vulnerability
    • YUI Weekly for May 10th, 2013

    Archives

    Categories

    • Accessibility (25)
    • CSS 101 (6)
    • Design (51)
    • Development (590)
    • Frontend Jobs at Yahoo (13)
    • Graded Browser Support (8)
    • In the Wild (63)
    • Miscellany (11)
    • Open Hours (44)
    • Performance (23)
    • Releases (25)
    • Target Environments (11)
    • Yeti (3)
    • YUI 3 Gallery (29)
    • YUI Events (45)
    • YUI Implementations (55)
    • YUI Theater (146)
    • YUI Weekly (37)

    Meta

    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
    © 2013 YUI Blog