Tuesday, December 14, 2010

YUI Conference 2010

I recently attended YUI's conference 2010. I created a small presentation which summarizes some of the most interesting sessions I watched during the three days of the conference.

Be aware! The presentation is written in HTML5 / CSS3, so I would suggest you to check it out in a decent browser, meaning Chrome/FF/Safari/IE9. ;)

Slides were based off http://slides.html5rocks.com/

Thursday, November 4, 2010

IE6 is about to die! w00t!!!

These news are amazing and couldn't resist sharing it with everyone!

According to YUIBlog, IE6 is going to be downgraded to C-grade browsers next quarter:

From YUIBlog:
"Forecast discontinuation of A-grade coverage for Internet Explorer 6 in Q1 2011; we expect to move IE6 to the C-grade browser list as of the next update."
At last our wish is coming true! Bye bye IE6...we won't miss you! :)





Sunday, October 3, 2010

A new website for Annual Reviews

On August 31, 2010, Atypon announced the launch of a refreshed website for Annual Reviews, one of the biggest publishers for scientific literature.
From the press release,
The refreshed website, www.AnnualReviews.org, [is] packed with innovative features that make it easier than ever for researchers to find principal contributions in their field and stay up to date with new developments, including:
  • The ability to quickly preview an article's figures from tables of contents, search results, and most popular content pages
  • Tag-along navigation that keeps an article's figures, references, and related content visible while moving through the article
  • Snippets from cited Annual Reviews articles that accompany the references, giving insight into the context of the citations

"As we continue to add content, features, and functions, this refresh provides a more effective interaction with our articles," said Steve Castro, CFO and Director of Sales and Marketing for Annual Reviews. "Our new review article page unlocks the full depth of our content, making it easier for researchers to discover the relevant literature and information they need."
I'm very happy I contributed to this release, in particular the review page, which you can preview at this sample article: www.AnnualReviews.org/r/sample.

Monday, September 13, 2010

BoomBox a side project...

Recently I've been playing with jquery and python. Panos and I have created Boombox, a site providing Greek music and in general music that's popular in Greece. Check it out!

Tuesday, September 7, 2010

XSLT recursion

XSLT sometimes can be a pain in the bum, for sure it's not one of my favorite languages. :)

So today, I was trying to fix the following problem:

XML snippet looked like this:

<tag1>
  text 1
  <tag11>
    <tag12>text 2</tag12>
  </tag11>
  text 3
  <tag21>
    text 4
    <tag22>text 5</tag22>
  </tag21>
  text 6
</tag1>

I wanted my output to look like this:

text 1 text 2 text 3 text 4 <a href="blah">text 5</a> text 6.

So pretty much what I needed to do was to get the text value of each node except from tag22 node, in which case I wanted to apply a template and output it as an anchor tag.

Here is the XSLT snippet which produces the desired result:

<xsl:apply-templates select="tag1" mode="foo"/>
<xsl:template match="text()" mode="foo">
  <xsl:value-of select"."/>
</xsl:template>
<xsl:template match="*" mode="foo">
  <xsl:apply-templates mode="foo"/>
</xsl:template>
<xsl:template match="tag22" mode="foo">
  <a href="blah"><xsl:value-of select="."/></a>
</xsl:template>

Let me try to explain whats going on here.

  1. mode=foo : mode is a pretty usefull attribute with XSLT, if an xsl:apply-templates element has a mode attribute, then it applies only to those template rules from xsl:template elements that have a mode attribute with the same value; if an xsl:apply-templates element does not have a mode attribute, then it applies only to those template rules from xsl:template elements that do not have a mode attribute. We need the mode attribute in this case because, we need to override the default behavior when matching all tags under tag1.
  2. match=text() : this is a NodeType test, this instruction will be matched for text nodes, in which case we'll just output their values (text itself)
  3. match=* : this will initially match any node which is first level child of tag1. After that we recursevily call <xsl:apply-templates mode="foo">, to apply matching templates for all descendants of tag1's first level children. So we will keep applying templates until we reach a leaf, in which case we'll output its content.



References:

Sunday, August 22, 2010

Making your menus accessible is really easy

WAI-ARIA, the Accessible Rich Internet Applications Suite, defines a way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with AJAX, HTML, JavaScript, and related technologies. Currently certain functionality used in Web sites is not available to some users with disabilities, especially people who rely on screen readers and people who cannot use a mouse (e.g mobile devices users). WAI-ARIA addresses these accessibility challenges, for example, by defining new ways for functionality to be provided to assistive technology. (http://www.w3.org/WAI/intro/aria)

So, trying to make our content more accessible is a pretty important step in web development. By including roles, states and properties, ARIA helps us make our code semantically richer for the assistive technology user. ARIA enables semantic description of an element or widget behavior and enables information about groups and the elements within them. ARIA states and properties are accessible via the DOM.

A common use case is a navigation menu. Almost every site/blog out there has a tabbed navigation menu. How could we make these menus more accessible..? It just takes few attributes in our dom elements, such as "role".

The ARIA "role" attribute

The role attribute enables us to create semantic structure on elements. Two notes about roles:
  1. once set, a role should not be dynamically changed, since this will confuse the assistive technology
  2. roles take precendence over element default semantic meaning

Menu Example

Here is a simple menu we see in many sites:
<div class="topMenuWrapper"> 
 <div class="topMenuWrapperInner"> 
  <ul class="topMenuList"> 
   <li class="topMenuListItem">
     <a href="#"><span class="menuItemContent">Menu item 1</span></a>
   </li>
   <li class="topMenuListItem">
     <a href="#"><span class="menuItemContent">Menu item 2</span></a>
   </li> 
   <li class="topMenuListItem">
     <a href="#"><span class="menuItemContent">Menu item 3</span></a>
   </li> 
   <li class="topMenuListItem">
     <a href="#"><span class="menuItemContent">Menu item 4</span></a>
   </li> 
  </ul> 
 </div>
</div>
By the way, here is the CSS to make a working example, with horizontal tabs:
body {
   background-color: #F8F8F8;
}

.topMenuWrapperInner {
   margin: 5em;
   float: right;
}

.topMenuList {
   margin: 0px; 
}

.topMenuListItem {
   margin-right: 10px; 
   padding: 6px;
   display:inline;
   background-color: #ddd;
   border: 1px solid #ddd;
  /* lets add rounded corners for real browsers :P */
   -webkit-border-top-left-radius:5px;
   -webkit-border-top-right-radius:5px;
   -moz-border-radius-topleft:5px;
   -moz-border-radius-topright:5px;
}

.topMenuListItem a {
   color: #fff;
   text-decoration: none;
   font-weight: bold;   
}

.topMenuListItem:hover {
   background-color: #fff;
   border: 1px solid #ddd;
}

.topMenuListItem:hover a {
   color: #B0B0B0;
}

.menuItemContent {
   padding:10px;
} 
Now let's make our top menu accessible:
<div class="topMenuWrapper"> 
 <div role="menu" class="topMenuWrapperInner"> 
  <ul role="presentation" class="topMenuList"> 
   <li role="presentation" class="topMenuListItem">
     <a href="#" role="menuitem">
      <span class="menuItemContent">Menu item 1</span>
     </a>
    </li>
    <li role="presentation" class="topMenuListItem">
     <a href="#" role="menuitem">
      <span class="menuItemContent">Menu item 2</span>
     </a>
    </li> 
    <li role="presentation" class="topMenuListItem">
     <a href="#" role="menuitem">
      <span class="menuItemContent">Menu item 3</span>
     </a>
    </li> 
    <li role="presentation" class="topMenuListItem">
     <a href="#" role="menuitem">
      <span class="menuItemContent">Menu item 4</span>
     </a>
    </li> 
   </ul> 
 </div>
</div>
Now let's see what each attribute means:
  1. role = menu: Offers a list of choices to the user.
  2. role = presentation: An element whose role is presentational does not need to be mapped to the accessibility API.
  3. role = menuitem: A link in a menu. This is an option in a group of choices contained in a menu.
As I mentined above, its pretty easy to make our sites accessible. One nice side effect is that if you also use suggested ARIA practices, you can make your site faster to navigate with the keyboard, which benefits all users. If you are using frameworks to build your own menus, be sure to use ones that provide WAI-ARIA support, such as:
  1. YUI3: MenuNav Node Plugin
  2. Tabs - JQuery accessible RIA
If you are interested in exploring ARIA further, here are some pretty usefull resources:
  1. WAI-ARIA Best Practices, http://www.w3.org/TR/2008/WD-wai-aria-practices-20080204/
  2. WAI-ARIA Roles, http://www.w3.org/TR/wai-aria/usage#usage_intro

Sunday, August 15, 2010

JS Performance and YUI3

Javascript performance in the browser is a pretty important usability issue we have to deal with every day. The problem starts from the fact that javascript is blocking, meaning that nothing else can happen while javascript code is being executed. Browsers use a single thread to execute JS code and update the UI. Whether we include a script tag within the body of our page or in an external file, the browser will stop rendering the page and it will wait to for the script to complete. Two good techniques to improve our page's performance are:
  • grouping scripts as much as possible
  • loading JS code after the page has finished loading (aka nonblocking scripts)
A good example to look at these techniques is the YUI library. Recently I worked with YUI3 which is, I think a pretty cool library. Let's see how it works:
Grouping Scripts
Every time we include an external JS file in our HTML, an HTTP request is issued, which by itself causes an additional performance penalty. Yahoo created the combo handler to distribute the YUI library files. YUI's users can pull any number of files by using a combo-handled URL, such as: "http://yui.yahooapis.com/combo?3.1.0/build/oop/oop-min.js&3.1.0/build/dom/dom-min.js&3.1.0/build/event-custom/event-custom-min.js&3.1.0/build/event/event-base-min.js". This URL includes 4 different files and there is no need to issue 4 different HTTP requests, we can just fetch all these files with one HTTP request. Pretty cool, right?
Nonblocking Scripts
YUI uses the concept of a small initial code on the page followed by downloading additional functionality later. To use YUI3 in our page we only need to include the YUI seed file:
<script type="text/javascript" src="yui-min.js"/>
The seed file is about 10KB (6KB gzipped) and includes enough functionality to download any other YUI components in the Yahoo CDN (content delivery network). For example, if we want to use the DOM utility, we just need to specify its name within the YUI use() method. The use method will provide a callback that will be executed when the code is ready, an example piece of code is:
YUI.use("dom", function(Y) {
   var testElmt = Y.one('#test123'); //gets element by id
   // do something with the element
});
This code creates a new instance of the YUI object and then calls the use() method. The seed file has all the information about filenames and dependencies, so specifying "dom" actually builds up a combo-habdler URL with all of the correct dependency files and creates a dynamic script element to download and execute those files. When all of the code is available the callback method is called and the YUI instance is passed in as the argument, allowing to immediately start using the newly downloaded functionality. The good thing with nonblocking scripts is that the JS files are downloaded as soon as the element is added in the page, so we don't need to actually block any other process in it.





References: High Performance JavaScript, Nicholas C. Zakas (http://oreilly.com/catalog/9780596802806)

Sunday, August 8, 2010

HTML Collections are LIVE!

  var allDivs = document.getElementsByTagName('div');
  for(var i = 0; i < allDivs.length; i++) {
     document.body.appendChild(document.createElement('div'));
  }

Do you see anything wrong in this snippet of code? You would expect it to create one additional div for every div element in the DOM, so it should just double the number of div nodes in the document, right? Well, not really! This is actually an infinite loop. Why? Because the loop's exit condition is never met, as allDivs.length increases by one with every iteration.

As defined in the DOM standard, HTML collections are "assumed to be live", meaning that they are automatically updated when the underlying document is updated.

So, here is the solution: Store the collection in a local variable, cache the length outside the loop and then use a local variable inside the loop for elements that are accessed more than once. e.g

  var coll = document.getElementsByTagName('div');
  var len = coll.length;
  for (var count = 0; count < len; count++) {
     // if needed cache in here the elements, to work with
     var el = coll[count];
     // do whatever
  }
This will do the magic and solve your problem!

Let's take it one step further. What if you want to touch every element you retrieve from this collection in a way that modifies the live collection. A common example is to replace a class from a collection of elements. e.g

  var allDivs = document.getElementsByClassName('class1');
  for (var i = 0; i < allDivs.length; i++) {
     allDivs[i].className = 'class2';
  }
This doesn't work, since allDivs changes with every iteration of the loop. In this case the best solution to go with is to actually copy the collection into an array and work with the array instead. Something like this:
  function toArray(collection) {
    var result = [];
    var len = collection.length;
    for (var i = 0; i < len; i++) { result[i] = collection[i]; }
    return result; 
  }
  
  var allDivs = document.getElementsByClassName('class1');
  var ar = toArray(coll); //copies a collection into an array
  for(var i = 0; i < ar.length; i++) {
     ar[i].className = 'class2';
  }

Now let's look at another neat solution to this problem (unfortunately not supported by all browsers, i.e Internet Explorer 6 and 7). The document.querySelectorAll() method, is provided as a native DOM method. What's cool with it? You can provide a CSS selector as an argument and it will return you a non-live NodeList, an array-like object containing matching nodes, which will not represent the live structure of the document. Let me note here that in W3C's DOM specifications NodeLists are live, but in the case of querySelectorAll(), its explicitly specified that the returned Nodelist is static (not-live)! So, with this method we don't need to be as verbose as we used to be, e.g instead of calling

var elmts = document.getElementsById('menu').getElementsByTagName('a');
we can do something like:
var elmts = document.querySelectorAll('#menu a');
and of course there's no need to cache/copy variables, in order to access them.

Last but not least...use a library if possible! Avoid dealing with this problem and let the library (e.g YUI, jQuery) do its magic!




References: High Performance JavaScript, Nicholas C. Zakas (http://oreilly.com/catalog/9780596802806)

Hello World!

Hi, my name is Yiota Tsakiri. I am a software engineer. I live in the San Fransisco Bay Area.


If you wonder about my site's name, it's inspired by the Yottabyte