yui (advanced)

Post on 20-Jan-2015

1.451 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Discussion on a few concepts in deeper detail on YUI with the Yahoo! Maktoob team in Jordan

TRANSCRIPT

Saurabh Sahni YDN Developer, Hacker, Evangelist

YUI (ADVANCED)

Jai SanthoshYDN Engineer, Hacker, Frontend Guy

Yahoo!

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

http://yuilibrary.com/

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Good Architecture!!

What’s in Smart Software?

• Reliability

• Maintainability

• Compatibility

• Extensibility

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Javascript Modules

// yuiblog.com/blog/2007/06/12/module-pattern

myLibrary.fizzbuzz = (function () {var myPrivateVar = "Fizz";

return {fizzbuzz: myPrivateVar + "buzz";

};})();

YUIModules

// fizzbuzz.js

YUI.add("fizzbuzz", function(Y) {

// Private variablevar myPrivateVar = "fizz";

// Export as public varaibleY.fizzbuzz = myPrivateVar + "buzz";

})

YUIModules

// DOMYUI().use("node", function (Y) {......});

// Calendar widgetYUI().use("calendar", function (Y) {......});

// YQL clientYUI().use("yql", function (Y) {......});

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

http://yuilibrary.com/yui/infrastructure/

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

http://yuilibrary.com/yui/infrastructure/

Y.Attribute// http://yuilibrary.com/yui/docs/attribute/#configurationYUI().use("attribute", function(Y) {

function MyClass(userValues) { // Use addAttrs, to setup default attributes for // your class, and mixing in user provided initial values var attributeConfig = { attrA : { // ... Configuration for attribute "attrA" ... }, attrB : { // ... Configuration for attribute "attrB" ... } }; this.addAttrs(attributeConfig, userValues);

};

Y.augment(MyClass, Y.Attribute);});

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

http://yuilibrary.com/yui/infrastructure/

Y.Base// http://yuilibrary.com/yui/docs/base/YUI().use("base", function(Y) { function MyClass(config) { // Invoke Base constructor, passing through arguments MyClass.superclass.constructor.apply(this, arguments); }

// Used to identify instances of this classMyClass.NAME = "myClass";

// "Associative Array", used to define the set of attributes

// added by this class.MyClass.ATTRS = { A : { // Attribute "A" configuration },

B : { // Attribute "B" configuration }};...

Y.Base...Y.extend(MyClass, Y.Base, { // Prototype methods for your new class // Tasks MyClass needs to perform during // the init() lifecycle phase initializer : function(cfg) { this._wrapper = Y.Node.create('<div

class="yui-wrapper"></div>'); },

// Tasks MyClass needs to perform during // the destroy() lifecycle phase destructor : function() { Y.Event.purgeElement(this._wrapper);

this._wrapper.get("parentNode").removeChild(this._wrapper);

this._wrapper = null; }

});});

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

http://yuilibrary.com/yui/infrastructure/

Y.EventTarget// http://yuilibrary.com/yui/docs/event-custom/YUI().use('event-custom', function (Y) { // EventTarget is available and ready for use.

// Add implementation code here.});

// Subscription callbacks receive fire() argumentsY.on('birthday', function (name, birthdate) { var age = new Date().getFullYear() - birthdate.getFullYear(); alert('Happy ' + age + ', ' + name + '!');});

// Fire EventsY.fire('birthday', { name: '"Uncle" Walt Whitman', birthdate: new Date(1819, 4, 31)});

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

http://yuilibrary.com/yui/infrastructure/

Y.Plugin// http://yuilibrary.com/yui/docs/event-custom/YUI().use('plugin', function (Y) {

// This AnchorPlugin is designed to be added to Node instances

function AnchorPlugin(config) { // Hold onto the host instance (a Node in this

case), this._node = config.host;}

// When plugged into a node instance, the plugin will be // available on the "anchors" property.AnchorPlugin.NS = "anchors";

AnchorPlugin.prototype = { disable: function() { var node = this._node; var anchors = node.queryAll("a"); anchors.addClass("disabled"); anchors.setAttribute("disabled", true); }};...

Y.Plugin...var container = Y.one("div.actions");

container.plug(AnchorPlugin);

container.anchors.disable();

container.unplug("anchors");

});

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

• Async loading

• Dynamic dependency resolution

• On-demand module loading

• CSS support

• ... and more

YUI Loader

YUI Loader{

combine: true,comboUrl: 'http://yui.yahooapis.com/combo?',baseUrl: '3.4.1/build',modules: { },groups: {

ymaps: { combine: true, base: '/ajaxapi-4/modules/', comboBase: 'http://l.yimg.com/zz/combo?', root: 'a/lib/map/v4/4.0.0.579/modules/', modules: { }, patterns: {

'gallery-': {}}

}},

...

YUI Loader – Module Options

• type• path• fullpath• requires• optional

• use• after• lang• condition

YUI Loader – Module Options

• type• path• fullpath• requires• optional

• use• after• lang• condition

YUI Loadermodules: {

...

'ymaps-core': { path: 'ymaps-core/ymaps-core-min.js', requires: ['event'] }, 'ymaps-config': { path: 'ymaps-config/ymaps-config-min.js', requires: ['ymaps-core', 'intl'], lang: ['en-US', 'en-GB', 'es-ES', 'es-MX', 'es-US', 'fr-FR', 'fr-CA', 'it-IT', 'de-DE'] }, 'jQuery': { fullpath: 'http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js' },

...

}

YUI Loader – Module Options

• type• path• fullpath• requires• optional

• use• after• lang• condition

YUI Loadermodules: {

...

'ymaps-stack': {use: ['node', 'event', 'event-custom']

}, 'gallery-graphics-vml': {

path: 'gallery-graphics-vml/gallery-graphics-vml-min.js', condition: {

test: function (Y) {var canvas =

document.createElement('canvas');return (!

document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1') && (!canvas || !canvas.getContext || !canvas.getContext('2d')));

},trigger: 'gallery-graphics',ua: 'ie',when: 'instead',

}

...}

YUI Loader – Applying Config

• Instance Config

• YUI_config

• YUI.GlobalConfig

• YUI.applyConfig

YUI Loader – Applying Config

...

YUI({ debug: true, combine: true, comboBase: 'http://mydomain.com/combo?', root: 'yui3/'}).use('node', function (Y) { // ...});

• Instance Config

YUI Loader – Applying Config

...

YUI_config = { debug: true, combine: true, comboBase: 'http://mydomain.com/combo?', root: 'yui3/'};

• YUI_config

YUI Loader – Applying Config

...

YUI.GlobalConfig = { debug: true, combine: true, comboBase: 'http://mydomain.com/combo?', root: 'yui3/'};

• YUI.GlobalConfig

YUI Loader – Applying Config

...

YUI.applyConfig({ debug: true, combine: true});YUI.applyConfig({ comboBase: 'http://mydomain.com/combo?', root: 'yui3/'});

• YUI.applyConfig

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Good Extensibility=

Good Code Structure

• Pseudo-classical

• Prototypal

• Augmentation (Class A + Class B)

• Plugins

• Class extensions (mixins)

• MVC

Class Structure Strategies

Artificial

Native• Pseudo-classical

• Prototypal

• Augmentation

• Plugins

• Class extensions

• MVC

Class structure strategies

Native

Class structure strategies

• Pseudo-classical

• Prototypal

Pseudo-classical(Old school)

Pseudo-classical

function SubClass() { // constructor}

SubClass.prototype = new SuperClass();

SubClass.prototype.someProperty = "booga!";SubClass.prototype.someMethod = function () { ... };...

SubClass.someStaticMethod = function () { ... };...

Y.extend = function (SubClass, SuperClass, proto, static);

function SubClass() { // constructor}

Y.extend(SubClass, SuperClass);

SubClass.prototype.someProperty = "booga!";SubClass.prototype.someMethod = function () { ... };...

SubClass.someStaticMethod = function () { ... };...

Y.extend = function (SubClass, SuperClass, proto, static)

Pseudo-classical

function SubClass() { // constructor}

Y.extend(SubClass, SuperClass, { someProperty: "booga!", someMethod : function () { ... }, ...});

SubClass.someStaticMethod = function () { ... };...

Y.extend = function (SubClass, SuperClass, proto, static)

Pseudo-classical

function SubClass() { // constructor}

Y.extend(SubClass, SuperClass, { someProperty: "booga!", someMethod : function () { ... }, ...}, { someStaticMethod: function () { ... }, ...});

Y.extend = function (SubClass, SuperClass, proto, static)

Pseudo-classical

Y.SubClass = Y.extend( function() { // constructor }, /* extends */ SuperClass, { // Instance members someProperty: "booga!", someMethod : function () { ... } }, { // Static members someStaticMethod: function () { ... } });

Y.extend = function (SubClass, SuperClass, proto, static)

Pseudo-classical

Y.extend() PROs

• Creates a “clean” subclass relationship

• no YUI class requirement

• Preserves instanceof

• SubClass.superclass (not super, but close)

• Control superclass constructor execution

Y.extend() CONs

• No multiple inheritance

• Manual constructor chaining required

• Constructor chaining is awkward

• Constructor chaining may be costly

• No multiple inheritance

• Manual constructor chaining required

• Constructor chaining is awkward

• Constructor chaining may be costly

function SubClass() { // Chain superclass constructor SubClass.superclass.constructor.apply(this, arguments); // My constructor stuff ...}

AWKWARDCOSTLY?

Y.extend() CONs

To sum up

• Good for basic class inheritance

• If you can extend Y.Base, there are more options

Prototypal

Prototypal

Y.extend = function(SubClass, SuperClass,...) { var superProto = SuperClass.prototype, subProto = Y.Object(superProto);

SubClass.prototype = subProto; ...

Y.extend = function(SubClass, SuperClass,...) { var superProto = SuperClass.prototype, subProto = Y.Object(superProto);

SubClass.prototype = subProto; ...

Prototypal

Y.Object = (function () {

function F() {} return function (obj) { F.prototype = obj; return new F(); };

})();

Prototypal

// Old and bustedSubClass.prototype = new SuperClass();

Constructor

SuperClass

Prototype{}

Constructor

SubClass

Prototype

f(n)Constructor

SuperClass

Prototype

f(n)

{}

Constructor

new

f(n)

Prototype{}

BAD

Prototypal

EMPTY Constructor

(anon)

Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj;’

return new F(); };})();

Constructor

SuperClass

Prototype

Constructor

SubClass

Prototype

f(n)

new

f(n)

{}Prototype

{}Prototype{} {}

Prototype

EMPTY Constructor

(anon)

Prototype

f(n)

{}

EMPTY Constructor

f(n)

Prototypal

Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); };})();

Any Object

EMPTY Constructor

(anon)f(n)

New Object{} {}

Prototype

EMPTY Constructor

(anon)f(n)

Prototype

{}

Prototypal

Factory constructor

function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that;}

function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that;}

var set = new Set(‘a’,’b’);

Factory constructor

function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that;}

var set = new Set(‘a’,’b’);

set instanceof Set; // true

Factory constructor

function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that;}

var set = Set(‘a’,’b’); // <-- OOPS! I forgot 'new'!

Factory constructor

function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that;}

var set = Set(‘a’,’b’);

set instanceof Set; // true

Factory constructor

Y.Object() PROs

• Avoids copying a lot of properties

• Can be used to make factory constructors

• Can be used to store original values for revert

• Any object can be the prototype

• Avoids class explosion

Y.Object() CONs

• No multiple inheritance

• Factory constructor can promote sloppiness

• Can’t use hasOwnProperty in for/in loops

To sum up

• Useful for some internal logic patterns

• Not a good fit for most web app problems

• Common use suggests need for a constructor

To sum up

var account1 = Y.Object(accountProto);account1.id = 1234;account1.holder = 'John Q. Consumer';

var account2 = Y.Object(accountProto);account2.id = 1235;account2.holder = 'Jane B. Investor';

• Useful for some internal logic patterns

• Not a good fit for most web app problems

• Common use suggests need for a constructor

To sum up

var account1 = Y.Object(accountProto);account1.id = 1234;account1.holder = 'John Q. Consumer';

var account2 = Y.Object(accountProto);account2.id = 1235;account2.holder = 'Jane B. Investor';

CONSTRUCTOR

• Useful for some internal logic patterns

• Not a good fit for most web app problems

• Common use suggests need for a constructor

To sum up

function Account(id, holder) { this.id = id; this.holder = holder;}

var account1 = new Account(1234, 'John Q. Consumer');var account2 = new Account(1235, 'Jane B. Invester');

• Useful for some internal logic patterns

• Not a good fit for most web app problems

• Common use suggests need for a constructor

Class structure strategies

Native✓ Pseudo-classical

✓ Prototypal

Artificial

• Augmentation

• Plugins

• Class extensions

• MVC

Augmentation

A C

B

Augmentation

Y.ModelList = Y.extend( function () { /* constructor */ ModeList.superclass.constructor.apply(this, arguments); },

Y.Base,

{ /* prototype */ }, { /* static */ }); Y.augment(Y.ModelList, Y.ArrayList);

Y.augment = function (to, from, force, whitelist, config)

Y.ModelList = Y.extend( function () { /* constructor */ ModeList.superclass.constructor.apply(this, arguments); },

Y.Base,

{ /* prototype */ }, { /* static */ }); Y.augment(Y.ModelList, Y.ArrayList);

Y.augment = function (to, from, force, whitelist, config)

Augmentation

Y.ModelList = Y.extend( function () { /* constructor */ ModeList.superclass.constructor.apply(this, arguments); },

Y.Base,

{ /* prototype */ }, { /* static */ }); Y.augment(Y.ModelList, Y.ArrayList);

Y.augment = function (to, from, force, whitelist, config)

Augmentation

list

ModelList

Prototype

Constructor

create

init

each

item

Y.augment(Y.ModelList, Y.ArrayList);

var list = new Y.ModelList({ ... });

list.each(function (item) { ... });

ModelList

Prototype

Constructor

create

init

ArrayList

Prototype

each

item

Constructor

each

item

Prototype

create

init

each

itemPrototype

new

Constructor

augment

Augmentation

list

item

each

ArrayList

Prototype

each

item

Constructor

Y.augment(Y.ModelList, Y.ArrayList);

var list = new Y.ModelList({ ... });

list.each(function (item) { ... });

ModelList

Prototype

Constructor

create

init

Prototype

each

item

each

Constructoreach 1. Copy

2. Construct

3. Execute

each

Augmentation

Y.augment(Y.HistoryBase, Y.EventTarget, null, null, { emitFacade : true, prefix : 'history', preventable: false, queueable : true});

Y.augment = function (to, from, force, whitelist, config)

Augmentation

Y.augment() PROs

• Defers constructor overhead

• Can augment with multiple classes

• Supports class or instance augmentation

• No YUI class requirement

Y.augment() CONs

• First augmented method call is costly

• instanceof is false for augmenting classes

• Consumes more memory

• Limited control of constructor invocation

To sum up

• Use it to simulate lazy multiple inheritance

• Y.Base-based classes should use class extensions

• Beware the diamond problem

• Weigh the importance of constructor deferral

To sum up

• Use it to simulate lazy multiple inheritance

• Y.Base-based classes should use class extensions

• Beware the diamond problem

• Weigh the importance of constructor deferral

Y.SubClass = Y.extend( function () { Y.SuperClass.apply(this, arguments); Y.EventTarget.apply(this, { /* config */ }); }, Y.SuperClass, // <-- one "official" extention class Y.mix({ /* prototype */ }, Y.EventTarget.prototype), { /* static */ });

Plugins

Aa a aa

Pluginsvar overlay = new Y.Overlay({ ... });

overlay.plug(Y.Plugin.Drag);

overlay.dd.set('lock', true);

overlay.unplug('dd');

var overlay = new Y.Overlay({ ... });

overlay.plug(Y.Plugin.Drag);

overlay.dd.set('lock', true);

overlay.unplug('dd');

Overlay

Attributes

x

y

Constructor

Overlay

ATTRS

x

y

Constructoroverlay

Attributes

x

y

Constructor

Plugins

overlay

Attributes

x

y

var overlay = new Y.Overlay({ ... });

overlay.plug(Y.Plugin.Drag);

overlay.dd.set('lock', true);

overlay.unplug('dd');

Overlay

ATTRS

x

y

Constructor

Plugin.Drag

Attributes

lock

Constructor

Plugin.Drag

ATTRS

lock

Constructor

overlay.ddAttributes

lock Constructordd

Plugins

var overlay = new Y.Overlay({ ... });

overlay.plug(Y.Plugin.Drag);

overlay.dd.set('lock', true);

overlay.unplug('dd');

Overlay

ATTRS

x

y

Constructor

Plugin.Drag

ATTRS

lock

Constructor

overlay

Attributes

x

y

overlay.ddAttributes

lock

dd

Plugins

var overlay = new Y.Overlay({ ... });

overlay.plug(Y.Plugin.Drag);

overlay.dd.set('lock', true);

overlay.unplug('dd');

Overlay

ATTRS

x

y

Constructor

Plugin.Drag

ATTRS

lock

Constructor

overlay

Attributes

x

y

overlay.ddAttributes

lock

dd

Plugins

The requirements

• Y.Plugin.Host (free in Y.Base, or add with Y.augment)

Host class

Plugin class

• Static NS property

That’s it

Plugins (instance)

Y.Plugin.Host.prototype.plug = function (Plugin, config) { ... if (Plugin && Plugin.NS) { config.host = this; this[Plugin.NS] = new Plugin(config); }};

Plugins (instance)

Y.Plugin.Host.prototype.plug = function (Plugin, config) { ... if (Plugin && Plugin.NS) { config.host = this; this[Plugin.NS] = new Plugin(config); }};

overlay.dd.set('lock', true);

overlay.unplug('dd');

The contract

SHOULD✓ Expect an object

constructor argument with ‘host’ property

✓ Provide namespaced API✓ Modify core behavior via

events or AOP

MAYSHOULD✓ Expect an object

constructor argument with ‘host’ property

The contract

✓ Provide namespaced API✓ Modify core behavior via

events or AOP

MAY

MUST✓ Remove all traces when

unplugged

SHOULD✓ Expect an object

constructor argument with ‘host’ property

The contract

✓ Provide namespaced API✓ Modify core behavior via

events or AOP

MAY

MUST✓ Remove all traces when

unplugged

MUST NOT✓ Modify host directly other

than add the namespace

SHOULD✓ Expect an object

constructor argument with ‘host’ property

The contract

Plugins (class)

Y.Plugin.Host.plug(Y.Overlay, Y.Plugin.Drag, { handles: ['.yui3-widget-hd']});

var overlay = new Y.Overlay({ ... });

overlay.dd.set('lock', true);

Plugin PROs

• Avoids method/property naming collisions

• Preserves host behavior when unplug()ed

• Plug classes or instances

• Generic plugins can work for multiple host types

• Works on Nodes

Plugin CONs

• Fragments API

• Plugin contract to restore host can add code weight

• Difficult to manage competing plugins

• plug() could use a little sugar

To sum up

• Flexible

• Better in smaller numbers

• Class Plugins vs Augmentation?

• Free with Y.Base-based classes and Y.Nodes

(have I mentioned that you should use Y.Base?)

Class Extensions

A C

B

Y.Base

Class extensionsY.extend = function (SubClass, SuperClass, proto, static)

Y.SubClass = Y.extend(

{ someProperty: ‘booga!’, someMethod : function () { ... } }, {

function() { SubClass.superclass.constructor.apply(this, arguments); },

/* extends */ Y.Base

NAME: ‘subsub’,

[], // <-- class extensions!

/* NAME */ ‘subsub’,

Y.Base.create = function(NAME, SuperClass, ext, proto, static)

ATTRS: { ... } });

Class extensionsY.Base.create = function(NAME, SuperClass, ext, proto, static)

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ],

{ /* Glue Y.Lines APIs to Y.CartesianSeries APIs */ });

Y.Base.create = function(NAME, SuperClass, ext, proto, static)

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ],

{ /* Glue Y.Lines APIs to Y.CartesianSeries APIs */ });

Y.ComboSeries = Y.Base.create('comboSeries', Y.CartesianSeries, [ Y.Fills, Y.Lines, Y.Plots ],

{ /* Glue Y.Fills etc APIs to Y.CartesianSeries APIs */ }, { ATTRS: { ... } });

Class extensions

Y.Base.create = function(NAME, SuperClass, ext, proto, static)

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ],

{ /* Glue Y.Lines APIs to Y.CartesianSeries APIs */ });

Y.ComboSeries = Y.Base.create('comboSeries', Y.CartesianSeries, [ Y.Fills, Y.Lines, Y.Plots ],

{ /* Glue Y.Fills etc APIs to Y.CartesianSeries APIs */ }, { ATTRS: { ... } });

Class extensions

LineSeries

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

LinesConstructor

ConstructorConstructor

Prototype

ATTRS

ATTRS

Prototype

CartesianConstructor

ATTRS

Prototype

Constructor Constructor

Class extensions

LineSeries

Prototype

ATTRS

ConstructorConstructor

Constructor

Constructor

ATTRS

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

LinesConstructor

ATTRS

Prototype

CartesianConstructor

ATTRS

Prototype

CartesianConstructor

ATTRS

Prototype

direction

type

LinesConstructor

ATTRS

Prototype

type

Class extensions

LineSeries

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

Prototype

Constructor

ATTRS

CartesianConstructor

ATTRS

Prototype

direction

type

LinesConstructor

ATTRS

Prototype

typedirection

type

type

+styles

Class extensions

LinesConstructor

ATTRS

Prototype

type

LinesConstructor

Prototype

ATTRS

drawLines

LineSeries

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

Prototype

Constructor

CartesianConstructor

ATTRS

Prototype

direction

type

ATTRS

direction

type

stylesATTRS

Prototype

CartesianConstructor

ATTRS

Prototype

draw

Class extensions

LinesConstructor

Prototype

ATTRS

drawLines

LineSeries

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

Constructor

ATTRS

Prototype

CartesianConstructor

ATTRS

Prototype

draw

Prototype

drawPrototype

drawdrawLines

drawSeries

Class extensions

LinesConstructor

Prototype

ATTRS

drawLines

LineSeries

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

Constructor

ATTRS

CartesianConstructor

ATTRS

Prototype

draw

Prototype

initializer

Prototype

initializerinitializer

initializer

initializer

initializer

Class extensions

Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... });

var series = new Y.LineSeries({ ... });

1. Constructors are called

2. Attributes are set

3. initializers are called

Class extensions

Two types of extensions

• Class decoration

• Core functionality

Add feature APIs and Attributes

Satisfy abstract class implementation

Y.Base.create = function(NAME, SuperClass, ext, proto, static)

Y.Overlay = Y.Base.create('overlay', Y.Widget, [ Y.WidgetStdMod, Y.WidgetPosition, Y.WidgetStack, Y.WidgetPosition, Y.WidgetPositionConstrain]);

Class extensions

Y.Base.mix = function(Class, ext)

Y.Slider = Y.Base.create('slider', Y.SliderBase,[Y.SliderValueRange]);

Y.Base.mix(Y.Slider, [Y.ClickableRail]);

Class extensions

Extensions PROs

• Promotes code reuse across environments

• Feature APIs are added to the prototype

• Can be used to mimic MVC breakdown

Extensions CONs

• Requires Y.Base

• Initialization overhead

• Class definition only (no instance feature additions)

• Does not work on Nodes

• Increased potential for accidental name collisions

Extension vs Plugin

• Extensions can be used to contribute core behavior

• Extensions modify the class prototype, plugins are always namespaced

• Feature extension constructors are always executed, plugin constructors on plug()

• Feature APIs/attributes on the prototype vs class plugins in namespace is a stylistic choice

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

YUI is Open!!

• Open Source

• Open CDN

• Open Hours

• Open Communication

• Open Development

• Open Documentation

References

• http://yuilibrary.com/

• Images from Google, Flickr

• http://www.youtube.com/yuilibrary

• Inheritance Patterns by @ls_n

Questions?

• Slides at http://slideshare.net/jaisanth

• Twitter: @jaisanth

• IRC freenode: #yui

THANK YOU!

top related