• 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 September, 2011

« Older Entries

YUIConf 2011 Early Bird Registration Is Now Open

Early-bird registration for YUIConf 2011 is now open on Eventbrite! This year’s event will be held November 2-4 on Yahoo!’s Great America campus. We’re excited to bring you a full day of hands-on training workshops (Wed) followed by two full days of tech talks about YUI (Thu/Fri). Registration for the conference costs $75 this year, with an early-bird rate of $50. Registration for the workshops will be separate from the conference and details are coming soon.

We are busy lining up great topics, including:

  • YUI component deep dives, including Dial and Calendar
  • YUI in mobile environments
  • Testing with YUI
  • Real-world migration stories
  • and much, much more!

As always, conference sessions will be video-taped and available on YUI Theater and our "http://www.youtube.com/user/yuilibrary">YouTube channel for all to enjoy.

Hope to see you there!

(IMPORTANT! Internal Yahoos please register for a Yahoo! Employee ticket and provide your work email address.)

By Jenny DonnellySeptember 30th, 2011

YUI 3.4.1 is now live

YUI 3.4.1

The YUI 3.4.1 short cycle release is now available on CDN and for download, more than a week early! Here are a few highlights for this release:

  • Over 150 bug fixes for Controller, Panel, DataTable, Calendar, and a number of other modules.
  • Bug fixes to Y.substitute() by YUI contributor Satyam.
  • Japanese language support for Calendar and Console, courtesy of YUI contributor Ryuichi Okumura.
  • Miscellaneous tweaks to the documentation and examples.

You can can also review the summary of all changes noted in the component history files for YUI 3.4.1 as well as the full list of tickets addressed during YUI 3.4.1 development. As always, we would appreciate that you file any suggestions you might have or defects you might uncover in our ticket database. Feedback for YUI 3.4.1 can be entered in the YUI 3 ticket database.

We would also like to announce that in the next release of YUI, DataType.Date, DataType.Number and DataType.XML will be deprecated in favor of Y.Date, Y.Number, and Y.XML, respectively. Backwards compatibility will be retained for one release, to give everyone a chance to switch over.

Oh, and one more thing: we are well on our way in migrating the YUI Theater content to YouTube. For starters, check out Douglas Crockford’s lecture series “Crockford on JavaScript” — complete with subtitles!

By Allen RabinovichSeptember 27th, 2011

Vote for YUI in the Open Source Awards Finals

Thanks to everyone who nominated YUI for the Packt Publishing Open Source Awards. Vote now for YUI as your favorite JavaScript library!

By Jenny DonnellySeptember 26th, 2011

YUI 3.4.1 PR1 Now Available On CDN

YUI 3.4.1 PR1 is now available for community testing and feedback. It is available on the Yahoo! CDN at http://yui.yahooapis.com/3.4.1pr1/build/yui/yui-min.js, and you can see the changes going into 3.4.1 from the list of tickets checked in for the release.

The 3.4.1 release will be a smaller bug-fix release with a shortened development cycle, scheduled for go-live by October 5th. Please file bugs and regressions in the ticket database on YUILibrary.com by the morning of Monday, September 26th so we can make sure any critical issues are addressed before the general release. If no urgent issues are reported, we will release 3.4.1 as early as September 27th.

By Jenny DonnellySeptember 22nd, 2011

YUI: Open Hours Thurs Sept 15th

Satyam’s MakeNode extension

If you don’t know Satyam, you must be new to YUI. He’s been a pillar of the YUI community since the early days of YUI 2. His articles on YUIBlog are some of the most read and referred to sources for “how to really use the library” style content. If you see that Satyam wrote it, it’s worth the read, and most likely, a re-read and a bookmark.

In July, he posted a great article on a MakeNode Widget extension that aims to simplify some of the common patterns used when building Widgets, and make it easier to avoid common missteps. The module has since been added to the Gallery and just earlier today, he posted an update to his original article.

That’s what we’re going to be talking about. The features, the history, and the reasonings. If you’ve been using the component infrastructure, and in particular, Y.Widget, you’ve likely encountered at least some of the hurdles Satyam set out to address with MakeNode. This is going to be a best practices fest, so bring your notepad, and your own experiences to share.

Time & Details

We’ll be online on Thursday from 10am to 11am PDT.

Join the Meeting

Recording

The recording is available in the YUILibrary YouTube channel.

By Luke SmithSeptember 12th, 2011

Submit a Talk for YUIConf 2011

Show off code you’ve been working on or share something you’ve learned while working with YUI! Submit your proposal to yui-events (at) yahoo-inc.com by Friday, September 23, 2011. Be sure to include:

  • Title
  • Description
  • Intended audience
  • Your name
  • A brief bio

YUIConf 2011 will be held November 3rd and 4th on Yahoo!’s Santa Clara, CA campus. Your presentation should last about 45 minutes. We’ll have up to 15 minutes after your presentation for Q&A. Post any questions in the comments, or email us directly at yui-events (at) yahoo-inc.com.

By Jenny DonnellySeptember 12th, 2011

Updated: The “MakeNode” Widget Extension

Editor’s Note: This article was originally published earlier this year. Since then, the MakeNode module has been published to the YUI Gallery and received some enhancements. Today’s article reflects all the latest changes to MakeNode.

In my previous article, A
Recipe for a YUI 3 Application
, I showed a way to use
Y.substitute as a very basic template
processor. The idea took life from there, with suggestions from the
folks in the #yui IRC channel, and I made it a Widget extension that
is available on the YUI Gallery, called MakeNode.
MakeNode is not a generic template processor and it is not meant as
one. On the other hand, it is tightly integrated with the YUI Widget

foundation class, including className and event helpers and
internationalization. In this article, I will take the Spinner
example and modify it to follow the guidelines from my previous
article and to use MakeNode. MakeNode
is available as a gallery component as well as the modified Spinner
component and the example
that will be used in this article.


Extending your component


To load MakeNode you need to include the module in your

YUI().use() statement using the name
‘gallery-makenode’or, if defining a
module via YUI.add(), list it as the
requires array. Then, to extend your
widget, you list it in the third argument to Y.Base.create(),
like this:


Y.Spinner = Y.Base.create(
‘Spinner’,
Y.Widget,
[Y.MakeNode],
{
// instance members …
},
{
// static members
}
);


You can add MakeNode along any number of suitable extensions for
Widget, such as WidgetParent, WidgetChild, WidgetStdMode, etc.
MakeNode adds two protected methods to be used by the developer,
_makeNode and _locateNodes,

and it will read from several static properties, if found.


All members of this extension are either protected or private
since they are meant to be used by the component developer and not by
the implementer using those components, who should not be bothered
with them. Remember to check the “Show Protected” option when viewing
the API
docs
.


Defining the template


The first thing you will normally do is to define the template for
your component. For the Spinner, our template will be:


_TEMPLATE: [
'<input type="text" title="{s input}" class="{c input}">',
'<button type="button" title="{s up}" class="{c up}"></button>',
'<button type="button" title="{s down}" class="{c down}"></button>'
].join(‘\n’),

The default template will usually be named _TEMPLATE
and declared along the other static properties of the class, such as
ATTRS. MakeNode will use this template
if none other is explicitly provided. The template is made of plain
HTML plus a series of placeholders enclosed in curly brackets, each
made of a single character (the processing code) and followed by one
or more arguments. The placeholders and what they produce are:



  • {@ attributeName} configuration
    attribute value


  • {p propertyName} instance
    property value

  • {m methodName arg1 arg2 ….}
    return value of the given method. The processing code is followed by
    the method name and any number of arguments separated by whitespace.


  • {c classNameKey} CSS className
    generated from the _CLASS_NAMES static
    property (see The _CLASS_NAMES property section below)


  • {s key} string from the strings

    attribute, using key as the
    sub-attribute.


  • {? condition
    valueIfTrue valueIfFalse}
    much like the ?: operator of
    JavaScript, evaluates to valueIfTrue if
    condition is truish, valueIfFalse

    otherwise.


  • {1 condition
    valueIfOne valueIfMore
    } used
    to produce singular/plural words based on the value of condition.


  • {} any other value will be
    handled just like Y.substitute does.


For example, {@ value} will translate
to this.get(‘value’) while {p
value}
translates to this['value'].


When placeholders have arguments, like {m},

{?} and {1},
strings must be enclosed in double quotation marks. Numbers, booleans
and null (all unquoted) will be parsed
to their proper data types. Placeholders can be nested. The {?}
and {1} placeholders will usually
contain a nested placeholder for the condition and quite possibly for
their values, for example:


{p qty} {1 {p qty} "unit" "units"} 

If the property qty is 1, it will
evaluate to "1 unit", for 2 or
more it will return "2 units"
and so on. A more elaborate version dealing with zero would be:


{? {p qty} "{p qty} {1 {p qty} "unit" "units"}" "none"} 

Note that the result of processing the inner placeholders, if a
string, must be enclosed in its own set of quotes.


To include a double quote inside a quoted string, use \\",
the double backslash being required because JavaScript will interpret
a single one and discards it before it gets to MakeNode. Only double
quotes are allowed; MakeNode does not use eval()
so the parser is limited but safe. Anything but numbers, null,
booleans and double quoted strings will be ignored.


The {?} placeholder is also handy to
use with checkboxes and radio buttons. It can be used to produce the
string "checked" depending on
the truth value of the processing instruction code that follows.
Thus, <input type="checkbox" {? {m
getLength} "checked" ""}/>
will produce
a marked checkbox if the getLength

method returns anything but zero.


For the {c} placeholder, we need to
have a _CLASS_NAMES property defined.


Further placeholders can be added to MakeNode by adding them into
the _templateHandlers hash.


The _CLASS_NAMES
property

Along with the ATTRS and _TEMPLATE
static properties, we can define a _CLASS_NAMES
static property which points to an array of strings. Each of those
strings will be used to generate a className. Thus _CLASS_NAMES:
['input']
will produce the className "yui3-spinner-input".
Those classNames are stored in an instance property this._classNames.
The {c input} placeholder in the
template above will be replaced by "yui3-spinner-input".
I call the strings listed in _CLASS_NAMES,
such as ‘input’, the “className keys”
since they can be used as a key to refer to the actual className or
the elements containing those classNames, as we’ll see later.

You can use the _CLASS_NAMES property
to generate any number of classNames, whether you use them in the
template or not. You can still reach those extra classNames from
within this._classNames. The className
is generated using the yui3 prefix
followed by the value of the NAME static
property turned lowercase, and then the string given in _CLASS_NAMES
(this last one will not be turned lowercase), all separated by
hyphens. The _classNames hash will also
contain the classNames for the boundingBox

and the contentBox, the first under the
"boundingBox" key and the second under
the "content" key. Widget
assigns to the boundingBox the
classNames derived from the values of the NAME
property of each of the classes in the inheritance chain, starting
with yui3-widget. MakeNode stores into

this._classNames only the top-most
className for the boundingBox.


If the WidgetStdMod module is loaded, MakeNode will also generate
entries for its HEADER, BODY
and FOOTER sections with those same
keys, which are also the constants defined in that same module.


If a component is several levels away from Widget, like

SuperSpecialSpinner inheriting from
SuperSpinner which inherits from Spinner
which inherits from Widget, and if any
or all of them have _CLASS_NAMES
properties defined, MakeNode will produce classNames for all of them
and store them in this._classNames. You
don’t need to include at each level the names already declared in the
previous levels. In fact, it is better that you don’t since the
classNames produced at each level will use the value of the NAME

property of that level. Thus, in SuperSpecialSpinner,
{c input} will still result in
"yui3-spinner-input" and not
"yui3-superspecialspinner-input"
and so it will keep your CSS file still valid.


The {s} placeholder


Widget has a strings configuration
attribute defined, though it is not initialized with any value. This
attribute is meant to hold strings that are visible to (or, via
screen readers, read to) the user. It is important that you never
include visible strings directly in the template. This is not a
requirement of MakeNode — it has never been a good idea at all. All
strings that are to be viewed by or read to the user should always be
placed in the strings attribute. The

strings attribute contains a hash where
each individual text is located by its key. The Spinner component has
the following strings, which you can see used in the template above.


strings: {
value: {
input: "Press the arrow up/down keys for minor increments, page up/down for major increments.",
up: "Increment",
down: "Decrement"
}
},


The best part of doing this is that your component can be localized
to other languages very easily by developers using your component.
When creating an instance of Spinner, you might do:


var mySpinner = new Spinner({strings: Y.Intl.get(‘spinner’)});

Setting the configuration attribute strings
in this way replaces the default strings
values with those from the language resource file using the language
previously defined. The {s} placeholder
accesses the strings stored in the strings
attribute, either the default ones or the translated ones, if set.
The {s xxxx} placeholder is almost like using {@ strings.xxxx}
except that the localized replacement strings can have placeholders which will be
further processed. This is important for translations since syntactical order varies
from language to language and this allows rephrasing the text, including its
placeholders to suit any language. Strings can also be accessed using
{@ strings.xxxx.yyyy.zzzz}, which will allow access to strings
nested deeper down and will prevent further substitutions. Curly braces can be included
in a text by using {LBRACE} and {RBRACE} as placeholders.

Using _makeNode in renderUI


We use the template to create the markup for our component. To do
so, we can call MakeNode’s _makeNode
method, like this:


renderUI : function() {
this.get(‘contentBox’).append(this._makeNode());
},


This will fill in the contentBox of our
widget with the markup from processing the template. The _makeNode
method returns an instance of Y.Node

which can be appended or inserted anywhere or just held for later
use. It does not return a string, it produces a Node
instance. (If you do need a string and not a Node, you can use
the _substitute method, which requires that you pass in a template.)


The _makeNode method takes two
optional arguments: a reference to a template and an object to fill
in placeholders, as Y.substitute does.
In our simple Spinner example there is a single template for the
whole widget but other widgets might require bits and pieces made out
of several templates. In that case, you would usually call _makeNode

with no arguments for the main part and call it once again with
different templates to fill in the extra parts. The example
contains this renderUI method:


renderUI: function () {
var fieldset = this._makeNode();
this.each(function (item) {
fieldset.appendChild(this._makeNode(MultipleTemplates.RADIO_TEMPLATE, item));
}, this);
this.get(‘contentBox’).append(fieldset);
}


The first call to _makeNode returns a
Node instance stored in the variable

fieldset. The sample component is also
extended with Y.ArrayList so the
RADIO_TEMPLATE will be filled with
values taken from the items stored in the array list and the
resulting Nodes appended to the fieldset
before it is finally appended to the contentBox.
The special placeholders such as {@} or
{p} will still refer to attributes or
properties in the main object. The nested items will be processed
just as Y.substitute would.

The _locateNodes method


MakeNode further provides a _locateNodes
method which will try to locate all the elements with the classNames
declared in _CLASS_NAMES. To locate
specific elements you can pass any number of className keys,
otherwise, _locateNodes tries them all.
For each element found of each className, _locateNodes
will produce a private instance property using the underscore prefix
followed by the key name and the "Node"
suffix. Thus, in our Spinner example, _locateNodes

will generate the properties _inputNode,
_upNode and _downNode.
If several elements have the same className, _locateNodes
will return a reference to the first of them. If an element is not
found, no variable will be created.


In the Spinner component we use _locateNodes
after creating the markup:

renderUI : function() {
this.get(CBX).append(this._makeNode());
this._locateNodes();
},


The _EVENTS static property


One further property can be defined along the lines of _TEMPLATE
and _CLASS_NAMES and that is _EVENTS.
_EVENTS will contain a hash made up of
class name keys, each containing a hash of event types and methods to
handle them. It is better explained with an example:

_EVENTS: {
input: ‘change’, // calls this._afterInputChange
boundingBox: [
{
type: 'key',
fn:'_onDirectionKey', // calls this._onDirectionKey
args:((!Y.UA.opera) ? "down:" : "press:") + "38, 40, 33, 34"
},
'mousedown' // calls this._afterBoundingBoxMousedown
],
document: ‘mouseup’, // calls this._afterDocumentMouseup,
Y: ‘broadcastingObject:someEvent’ // calls this["_afterYBroadcastingObject:someEvent"]
},


_EVENTS is an object (a hash) with any
number of entries. The names of the properties, that is, the keys of
the hash, identify the nodes whose events we will listen to. They are
the same className keys defined in _CLASS_NAMES.
There are several extra special keys:


  • "boundingBox" will
    refer to the bounding box itself.


  • "document" refers to
    the document containing this widget.


  • "THIS" refers to the
    widget itself


  • "Y" refers to the Y

    instance.



If the Widget has been extended with WidgetStdMod as well, the
keys HEADER, BODY
and FOOTER will refer to those sections
since they will be available in the _classNames
hash. JavaScript does not need the keys to be quoted if they are
valid identifiers so none of the above need to be quoted.

The _EVENTS property is processed
after the renderUI, bindUI
and syncUI methods have been called so
the widget is expected to be already inserted within the document
body, otherwise the "document" identifier will
fail.


For each of those elements there is an event identifier or an
array of event identifiers. An event can be identified by the type
of event to listen to or an object with further details. By default,
MakeNode will use as a listener a method named using the "_after"

prefix followed by the element identifier with its first character
capitalized followed by the event type with its first character
capitalized. The code block above shows the methods called for each
event.


An event identifier can also be an object with properties type,
fn and args.
The type is mandatory and indicates the
type of event being listened to. The fn
property gives the name of the method that will listen to the event
thus avoiding the automatic naming. Since _EVENTS

is a static property, it has no access to this
so it cannot take an actual reference to a method, only its name.
The args argument can be used to pass
further arguments to the caller such as with the key
event which requires a keys specification.


MakeNode will use Node.delegate to
listen to events on elements within the boundingBox,
while it will use Node.after to listen
to events from the boundingBox and the
document body. It will use this.after to
listen to events under the THIS key and

Y.after for listeners listed under the Y
key. All events are listened to using after event listeners
since they are meant to make the widget respond to events, not to
filter the behavior of the object that fires them so in no case these
events can be prevented or stopped. (Note: listening to the key
event on any nested element works only with version 3.4.0pr1 and
above, since delegation of the key event
was not available before. All the other features work with previous
versions as well).


The _EVENTS declarations are
cumulative when components inherit from one another. Each class in
the inheritance chain will have its own _EVENTS

declaration processed separately.


The _ATTRS_2_UI static property


Events go both ways, from the UI to the component and from the
component to the UI. The first are handled by the _EVENTS
property. Then there are the events fired by attribute value changes
that need to be reflected in the user interface. As I mentioned in
the previous article, when there are any secondary effects from
changing a configuration attribute, they should be handled by change
event listeners, not by the optional setter
method of the attribute, which should only deal with normalizing the
value being set. The UI should reflect the state of the configuration
attributes, first in syncUI, when being
initialized and then on every attribute change event. For the latter,
we need to attach an event listener, which we would normally do in
bindUI. Widget already provides a
mechanism to make that simple, which I described in the comments to
the previous article.

Widget uses the instance property _UI_ATTRS
that contains an object with two further properties, SYNC
and BIND. Each of these is an array
listing the names of the configuration attributes to be initially
synched and then listened to in order to keep the UI reflecting
current values. Widget expects each of those entries to have a method
associated with it, named after the attribute name prefixed by _uiSet
with the first character of the attribute name converted to uppercase
to have the method name in proper camel case. Thus, if "value"
was listed in any of the _UI_ATTRS

arrays (in either SYNC or BIND),
Widget would expect to find a _uiSetValue
method. This method will receive two arguments, the value
being set and the src of the change.
This is the code for our Spinner _uiSetValue

method:


_uiSetValue : function(value, src) {
if (src === UI) {
return;
}
this._inputNode.set(VALUE, this.get(FORMATTER)(value));
},


All the uppercase identifiers you see in this piece of code
correspond to string constants declared elsewhere, to allow the YUI
compressor to do its job better. The method, basically, sets the
value HTML attribute in the <input>
box to the new value set, after being formatted. The reference to the
textbox was provided by _locateNodes.
The src argument is initially checked to
see if set to the string value ‘ui’. If
this is so, no action will be taken. This is to avoid endless loops.
If the user enters something in the input box, its value would go
into the value configuration attribute
which then would fire a valueChange

event, which would get _uiSetValue
called which, if unchecked, would then go and change the value of the
input box, which would trigger the whole process again. Thus, in
_uiSetValue, if we know the change comes
from the UI, we do nothing and so break the loop. However, this
requires another piece of code elsewhere. In the listener for the DOM
event, when we set the configuration attribute, we use the third
optional argument to set, like this:


_afterValueChange : function(ev) {
this.set(VALUE, ev.newVal, {src: UI});
}


It is up to us to ensure that changes coming from the UI are flagged
thus and then check that same flag to avoid loops. Do use the
identifier src when setting the value of
the attribute, not source which will not
be recognized.

With all this said, I haven’t yet talked about the static property
_ATTRS_2_UI mentioned in the heading of
this section. As the comments in my previous article shows (through
the blunders I made in them), making sure that all attributes
affecting the UI are properly listed is somewhat messy. You should
never initialize _UI_ATTRS from scratch
since Widget already lists a whole lot of attributes and those would
be lost. You have to concatenate new attribute names over the
existing ones, which is somewhat hard to remember how to do it right.
To make it simple, MakeNode will read from the static property
_ATTRS_2_UI and do that concatenation
for you. It will concatenate all such lists from each and every class
in the inheritance chain so at each level each class can handle its
own attributes. In Spinner, we have:


_ATTRS_2_UI: {
BIND: VALUE,
SYNC: VALUE
},


MakeNode will accept both an array of names or a single attribute
name, as in this case.


The question naturally arises, why two lists, one for binding the
other for syncing? SYNC is used the
first time around, after the renderUI

and bindUI methods, if they exist, are
called and before syncUI while those
listed in BIND will be bound to the
corresponding attributes for later changes. Quite often the SYNC
array has fewer entries than the BIND
list and this is because the template for the component might already
have the very same default value as the configuration attribute and
there is no need to do an initial syncing. So, if the default value
for the value configuration attribute is
an empty string and the <input>

element in the template has no value
attribute, then there is no need to sync them on initialization.


Attributes listed in BIND will have
their _uiSetXxxx
methods called in any order, as attributes can be set in any order.
Attributes listed in SYNC will be called
once in the order in which they are listed with those of ancestors before their inheritors, so if one is dependent
on another (which they shouldn’t), the order might be important.

MakeNode will check for duplicate entries in any of these arrays.
If any appear, it means that a class our component inherits from
already handles this attribute and any new declaration would most
likely overstep the _uiSetXxxx
handler for it. Incidentally, MakeNode also checks for duplicate
entries in _CLASS_NAMES, which can also
cause conflict in some, though not all, circumstances. MakeNode will
write a message to the log for any such error.


The _PUBLISH property


Finally, the _PUBLISH static property
will list those events that have to be published. It contains a hash
using the name of the event as its keys and an object literal of
configuration attributes as its values. It will publish all the
events listed in any such property in all the inheritance chain. The
same event name can be published in a class and in any class
inheriting from it, which will make the configuration attributes of
later ones override the ones in the older ones. For example, you
might want to make an existing event broadcast globally. Just as with
the _EVENTS property, since _PUBLISH

is a static property without access to this,
when specifying functions, it is the name of the method, as a string,
that needs to be given.


Conclusion


MakeNode provides a very simple template processor, with
functionality that is highly integrated with the Widget foundation
class. It also provides helper methods to create classNames to be
used in the template and to use those names to locate and refer to
the nodes created. It also provides the means to hook into the events
generated both by the UI and the component itself and associate each
with a method. It does all these things, while taking care to respect
the inheritance chain straight up to Widget and any level of classes
you may define.


It does not provide for absolutely all possibilities, but covers a
good range of them. Nevertheless, it does not preclude you from
adding extra functionality. You might rarely have to write a bindUI
or syncUI method if you use the glue
provided by MakeNode, but you may do so, since MakeNode does not use
them.


As a bonus to those who had the patience to read this far, I have
also modified Anthony Pipkin’s Button set of gallery components and
made an Accordion and TimeSpinner components, all available in the

Gallery.

SatyamAbout the author: Daniel Barreiro (screen name Satyam) has been around for quite some time. The ENIAC was turned off the day before he was born, so he missed that but he hasn’t missed much since. He’s had a chance to punch cards, program 6502 chips (remember the Apple II?), own a TRS-80 and see some fantastic pieces of operating equipment in his native Argentina which might have been in museums elsewhere. When globalization opened the doors to the world, his then barely usable English (plus an Electrical Engineering degree) put him on the career path which ended in a 5-year job in the Bay Area back in the days of NCSA Mosaic. Totally intrigued by the funny squiggles a friend of his wrote in his plain text editor, full of <’s and >’s, he ended up learning quite a lot about the world of frontend engineering. It’s been a long journey since COBOL and Fortran. Now he lives quite happily semi-retired in the Mediterranean coast close to Barcelona, Spain.

By SatyamSeptember 12th, 2011
« 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