yui (advanced)

122
Saur YUI (ADVANCED) Jai Santhosh YDN Engineer, Hacker, Frontend Guy Yahoo!

Upload: jai-santhosh

Post on 20-Jan-2015

1.451 views

Category:

Technology


1 download

DESCRIPTION

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

TRANSCRIPT

Page 1: YUI (Advanced)

Saurabh Sahni YDN Developer, Hacker, Evangelist

YUI (ADVANCED)

Jai SanthoshYDN Engineer, Hacker, Frontend Guy

Yahoo!

Page 2: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 3: YUI (Advanced)

http://yuilibrary.com/

Page 4: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 5: YUI (Advanced)

Good Architecture!!

Page 6: YUI (Advanced)
Page 7: YUI (Advanced)
Page 8: YUI (Advanced)

What’s in Smart Software?

• Reliability

• Maintainability

• Compatibility

• Extensibility

Page 9: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 10: YUI (Advanced)

Javascript Modules

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

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

return {fizzbuzz: myPrivateVar + "buzz";

};})();

Page 11: YUI (Advanced)

YUIModules

// fizzbuzz.js

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

// Private variablevar myPrivateVar = "fizz";

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

})

Page 12: YUI (Advanced)

YUIModules

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

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

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

Page 13: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 14: YUI (Advanced)

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

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

Page 15: YUI (Advanced)

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

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

Page 16: YUI (Advanced)

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);});

Page 17: YUI (Advanced)

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

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

Page 18: YUI (Advanced)

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 }};...

Page 19: YUI (Advanced)

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; }

});});

Page 20: YUI (Advanced)

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

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

Page 21: YUI (Advanced)

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)});

Page 22: YUI (Advanced)

YUI Infrastructure• Attribute

• Base

• EventTarget

• Plugin

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

Page 23: YUI (Advanced)

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); }};...

Page 24: YUI (Advanced)

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

container.plug(AnchorPlugin);

container.anchors.disable();

container.unplug("anchors");

});

Page 25: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 26: YUI (Advanced)

• Async loading

• Dynamic dependency resolution

• On-demand module loading

• CSS support

• ... and more

YUI Loader

Page 27: YUI (Advanced)

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-': {}}

}},

...

Page 28: YUI (Advanced)

YUI Loader – Module Options

• type• path• fullpath• requires• optional

• use• after• lang• condition

Page 29: YUI (Advanced)

YUI Loader – Module Options

• type• path• fullpath• requires• optional

• use• after• lang• condition

Page 30: YUI (Advanced)

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' },

...

}

Page 31: YUI (Advanced)

YUI Loader – Module Options

• type• path• fullpath• requires• optional

• use• after• lang• condition

Page 32: YUI (Advanced)

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',

}

...}

Page 33: YUI (Advanced)

YUI Loader – Applying Config

• Instance Config

• YUI_config

• YUI.GlobalConfig

• YUI.applyConfig

Page 34: YUI (Advanced)

YUI Loader – Applying Config

...

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

• Instance Config

Page 35: YUI (Advanced)

YUI Loader – Applying Config

...

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

• YUI_config

Page 36: YUI (Advanced)

YUI Loader – Applying Config

...

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

• YUI.GlobalConfig

Page 37: YUI (Advanced)

YUI Loader – Applying Config

...

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

• YUI.applyConfig

Page 38: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 39: YUI (Advanced)

Good Extensibility=

Good Code Structure

Page 40: YUI (Advanced)

• Pseudo-classical

• Prototypal

• Augmentation (Class A + Class B)

• Plugins

• Class extensions (mixins)

• MVC

Class Structure Strategies

Page 41: YUI (Advanced)

Artificial

Native• Pseudo-classical

• Prototypal

• Augmentation

• Plugins

• Class extensions

• MVC

Class structure strategies

Page 42: YUI (Advanced)

Native

Class structure strategies

• Pseudo-classical

• Prototypal

Page 43: YUI (Advanced)

Pseudo-classical(Old school)

Page 44: YUI (Advanced)

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);

Page 45: YUI (Advanced)

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

Page 46: YUI (Advanced)

function SubClass() { // constructor}

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

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

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

Pseudo-classical

Page 47: YUI (Advanced)

function SubClass() { // constructor}

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

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

Pseudo-classical

Page 48: YUI (Advanced)

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

Page 49: YUI (Advanced)

Y.extend() PROs

• Creates a “clean” subclass relationship

• no YUI class requirement

• Preserves instanceof

• SubClass.superclass (not super, but close)

• Control superclass constructor execution

Page 50: YUI (Advanced)

Y.extend() CONs

• No multiple inheritance

• Manual constructor chaining required

• Constructor chaining is awkward

• Constructor chaining may be costly

Page 51: YUI (Advanced)

• 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

Page 52: YUI (Advanced)

To sum up

• Good for basic class inheritance

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

Page 53: YUI (Advanced)

Prototypal

Page 54: YUI (Advanced)

Prototypal

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

SubClass.prototype = subProto; ...

Page 55: YUI (Advanced)

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

SubClass.prototype = subProto; ...

Prototypal

Page 56: YUI (Advanced)

Y.Object = (function () {

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

})();

Prototypal

Page 57: YUI (Advanced)

// 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

Page 58: YUI (Advanced)

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

Page 59: YUI (Advanced)

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

Page 60: YUI (Advanced)

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;}

Page 61: YUI (Advanced)

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

Page 62: YUI (Advanced)

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

Page 63: YUI (Advanced)

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

Page 64: YUI (Advanced)

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

Page 65: YUI (Advanced)

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

Page 66: YUI (Advanced)

Y.Object() CONs

• No multiple inheritance

• Factory constructor can promote sloppiness

• Can’t use hasOwnProperty in for/in loops

Page 67: YUI (Advanced)

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

Page 68: YUI (Advanced)

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

Page 69: YUI (Advanced)

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

Page 70: YUI (Advanced)

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

Page 71: YUI (Advanced)

Class structure strategies

Native✓ Pseudo-classical

✓ Prototypal

Artificial

• Augmentation

• Plugins

• Class extensions

• MVC

Page 72: YUI (Advanced)

Augmentation

A C

B

Page 73: YUI (Advanced)

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)

Page 74: YUI (Advanced)

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

Page 75: YUI (Advanced)

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

Page 76: YUI (Advanced)

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

Page 77: YUI (Advanced)

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

Page 78: YUI (Advanced)

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

Page 79: YUI (Advanced)

Y.augment() PROs

• Defers constructor overhead

• Can augment with multiple classes

• Supports class or instance augmentation

• No YUI class requirement

Page 80: YUI (Advanced)

Y.augment() CONs

• First augmented method call is costly

• instanceof is false for augmenting classes

• Consumes more memory

• Limited control of constructor invocation

Page 81: YUI (Advanced)

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

Page 82: YUI (Advanced)

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 */ });

Page 83: YUI (Advanced)

Plugins

Aa a aa

Page 84: YUI (Advanced)

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

overlay.plug(Y.Plugin.Drag);

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

overlay.unplug('dd');

Page 85: YUI (Advanced)

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

Page 86: YUI (Advanced)

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

Page 87: YUI (Advanced)

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

Page 88: YUI (Advanced)

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

Page 89: YUI (Advanced)

The requirements

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

Host class

Plugin class

• Static NS property

That’s it

Page 90: YUI (Advanced)

Plugins (instance)

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

Page 91: YUI (Advanced)

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');

Page 92: YUI (Advanced)

The contract

SHOULD✓ Expect an object

constructor argument with ‘host’ property

Page 93: YUI (Advanced)

✓ Provide namespaced API✓ Modify core behavior via

events or AOP

MAYSHOULD✓ Expect an object

constructor argument with ‘host’ property

The contract

Page 94: YUI (Advanced)

✓ 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

Page 95: YUI (Advanced)

✓ 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

Page 96: YUI (Advanced)

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);

Page 97: YUI (Advanced)

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

Page 98: YUI (Advanced)

Plugin CONs

• Fragments API

• Plugin contract to restore host can add code weight

• Difficult to manage competing plugins

• plug() could use a little sugar

Page 99: YUI (Advanced)

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?)

Page 100: YUI (Advanced)

Class Extensions

A C

B

Y.Base

Page 101: YUI (Advanced)

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: { ... } });

Page 102: YUI (Advanced)

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 */ });

Page 103: YUI (Advanced)

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

Page 104: YUI (Advanced)

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

Page 105: YUI (Advanced)

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

Page 106: YUI (Advanced)

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

Page 107: YUI (Advanced)

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

Page 108: YUI (Advanced)

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

Page 109: YUI (Advanced)

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

Page 110: YUI (Advanced)

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

Page 111: YUI (Advanced)

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

Page 112: YUI (Advanced)

Two types of extensions

• Class decoration

• Core functionality

Add feature APIs and Attributes

Satisfy abstract class implementation

Page 113: YUI (Advanced)

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

Page 114: YUI (Advanced)

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

Page 115: YUI (Advanced)

Extensions PROs

• Promotes code reuse across environments

• Feature APIs are added to the prototype

• Can be used to mimic MVC breakdown

Page 116: YUI (Advanced)

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

Page 117: YUI (Advanced)

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

Page 118: YUI (Advanced)

What We’re Going to Cover

• Why YUI?

• Modularity

• YUI Infrastructure

• YUI Loader – Deep dive

• Extensibility– Native and Artificial Code Structuring

• YUI is Open!

Page 119: YUI (Advanced)

YUI is Open!!

• Open Source

• Open CDN

• Open Hours

• Open Communication

• Open Development

• Open Documentation

Page 120: YUI (Advanced)

References

• http://yuilibrary.com/

• Images from Google, Flickr

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

• Inheritance Patterns by @ls_n

Page 121: YUI (Advanced)

Questions?

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

• Twitter: @jaisanth

• IRC freenode: #yui

Page 122: YUI (Advanced)

THANK YOU!