Created
May 21, 2010 22:04
-
-
Save jakobo/409496 to your computer and use it in GitHub Desktop.
A "backwards" class library for JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sslac - A "backwards" class library for JavaScript | |
* Provides a consistent way to declare classes to ease 1st and 3rd | |
* party development by using closures. | |
* Features: | |
* - auto extension: Objects can be set to extend by default, allowing for | |
* easy inheritance of this.* properties as well as prototyped methods | |
* - consistent privileged interface: this.* assignments are handled by the | |
* framework. | |
* - static and instance functionality: Can create both statuc and instance | |
* level objects | |
* @class Sslac | |
* @author Jakob Heuser <jheuser@linkedin.com> | |
*/ | |
(function() { | |
var NAMESPACE = "Sslac"; | |
window[NAMESPACE] = window[NAMESPACE] || {}; | |
/** | |
* extend an object and assign parent to .superclass | |
* @license BSD | |
* @author YUI | |
*/ | |
var extend = function(subc, superc, overrides) { | |
var F = function() {}; | |
F.prototype = superc.prototype; | |
subc.prototype = new F(); | |
subc.prototype.constructor = subc; | |
subc.superclass = superc.prototype; | |
if (superc.prototype.constructor == Object.prototype.constructor) { | |
superc.prototype.constructor = superc; | |
} | |
if (overrides) { | |
for (i in overrides) { | |
if (overrides.hasOwnProperty(overrides, i)) { | |
subc.prototype[i]=overrides[i]; | |
} | |
} | |
} | |
}; | |
/** | |
* get the namespace object of a given ns | |
* @param {String} namespace | |
* @return {Object} the parent NS (for insertion) | |
*/ | |
var namespaceOf = function(ns) { | |
var i, | |
piece, | |
scope, | |
pieces = ns.split(/\./), | |
len = pieces.length; | |
// loop through all pieces | |
for (i = 0, scope = window; i < len; i++) { | |
piece = pieces[i]; | |
// if not a match, drill down one further | |
if (i + 1 == len) { | |
return scope; | |
} | |
scope[piece] = scope[piece] || {}; | |
scope = scope[piece]; | |
} | |
}; | |
/** | |
* Get the endpoint name of a namespace | |
* for example: Foo.Bar.Baz => Baz | |
* @param {String} the namespace | |
* @param {String} the endpoint name | |
*/ | |
var nameOf = function(ns) { | |
var pieces = ns.split(/\./), | |
last = pieces[pieces.length - 1]; | |
return last; | |
}; | |
// The "root" of all evil. Really, just an object that gaurentees a base heirarchy | |
var Class = function() {}; | |
/** | |
* Root chaining object for Sslac. Takes a namespace and isStatic | |
* this is the base object for construction of Sslac classes | |
* @class ObjectRef | |
*/ | |
var ObjectRef = function(ns) { | |
var parent = null; | |
var localConstructor = function() {}; | |
var privilegedMethods = {}; | |
var F = function() { | |
var namespace = ns; | |
if (parent) { | |
this.Parent = parent.constructor.apply(this, arguments); | |
} | |
for (name in privilegedMethods) { | |
this[name] = privilegedMethods[name]; | |
} | |
return localConstructor.apply(this, arguments); | |
}; | |
/** | |
* defines a constructor | |
* @method Constructor | |
* @param {Function} the function to set | |
* @return this | |
*/ | |
this.Constructor = function(fn) { | |
localConstructor = fn; | |
return this; | |
}; | |
/** | |
* defines a method (this.* syntax) | |
* @method Method | |
* @param {String} the name to store | |
* @param {Function} the function to set | |
* @return this | |
*/ | |
this.Method = function(name, fn) { | |
privilegedMethods[name] = fn; | |
return this; | |
}; | |
/** | |
* Explicitly put something on the prototype | |
* @method Prototype | |
* @param {String} the name to store | |
* @param {Function} the function to set | |
* @return this | |
*/ | |
this.Prototype = function(name, fn) { | |
F.prototype[name] = fn; | |
return this; | |
}; | |
/** | |
* Explicitly put something on the static object | |
* @method Static | |
* @param {String} the name to store | |
* @param {Function} the function to set | |
* @return this | |
*/ | |
this.Static = function(name, fn) { | |
F[name] = fn; | |
return this; | |
}; | |
/** | |
* define the superclass of this object | |
* @method Extends | |
* @param {String|Object} the object to extend | |
* @return this | |
*/ | |
this.Extends = function(name) { | |
if (typeof(name) == "string") { | |
name = namespaceOf(name)[nameOf(name)]; | |
} | |
extend(F, name); | |
parent = F.superclass; | |
return this; | |
}; | |
// extend default class | |
this.Extends(Class); | |
var placeNS = namespaceOf(ns); | |
var placeName = nameOf(ns); | |
placeNS[placeName] = F; | |
}; | |
// create object | |
var createObject = function(ns) { | |
return new ObjectRef(ns); | |
}; | |
// create static object | |
var createStaticObject = function(ns) { | |
// todo: add protection against delcaring memebrs in static mode | |
return new ObjectRef(ns); | |
}; | |
// helper to create a function | |
var createFunction = function(ns, fn) { | |
var placeNS = namespaceOf(ns); | |
var placeName = nameOf(ns); | |
placeNS[placeName] = fn; | |
}; | |
// helper to just define a namespace | |
var defineNamespace = function(ns) { | |
var placeNS = namespaceOf(ns); | |
var placeName = nameOf(ns); | |
placeNS[placeName] = placeNS[placeName] || {}; | |
}; | |
// assign outward | |
window[NAMESPACE].Class = createObject; | |
window[NAMESPACE].Static = createStaticObject; | |
window[NAMESPACE].Function = createFunction; | |
window[NAMESPACE].Define = defineNamespace; | |
window[NAMESPACE].ClassObject = Class; | |
})(); | |
// licensing block | |
// extend() | |
/* | |
Copyright (c) 2010, Yahoo! Inc. | |
All rights reserved. | |
Redistribution and use of this software in source and binary forms, with or | |
without modification, are permitted provided that the following conditions are | |
met: | |
* Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
* Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
* Neither the name of Yahoo! Inc. nor the names of its contributors may be used | |
to endorse or promote products derived from this software without specific prior | |
written permission of Yahoo! Inc. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------------------------------------------------------------------------------------------------- | |
// Main Connect Framework | |
// ---------------------------------------------------------------------------------------------------- | |
/** | |
* TagParser responsible for finding the LI Connect tags and handling them | |
* @class LIx.TagParser | |
* @constructor | |
*/ | |
Sslac.Class("LIx.TagParser") | |
.Constructor(function() { | |
this.tagRegistry = {}; | |
}) | |
/** | |
* process a match for a tag | |
* @param node {HTMLElement} | |
* @private | |
* @method processTagMatch | |
*/ | |
.Method("processTagMatch", function(node) { | |
var tagName = node.tagName.toLowerCase(); | |
var name; | |
// normalize tags for entry, handle non qualifying tags | |
switch(tagName) { | |
case "li:connect": | |
name = node.getAttribute("name"); | |
break; | |
case "embed": | |
if (!node.getAttribute("data-li")) { | |
return; | |
} | |
name = node.getAttribute("name"); | |
break; | |
} | |
if (!this.tagRegistry[name]) { | |
return false; | |
} | |
// extract the attributes | |
var obj, container, attr = {}; | |
for(var i = 0, attrs = node.attributes, len = attrs.length; i < len; i++) { | |
if (LIx.Util.support.li_attributesSpecified) { | |
attr[attrs.item(i).nodeName] = attrs.item(i).nodeValue; | |
} | |
else { | |
if (attrs.item(i).specified) { | |
attr[attrs.item(i).nodeName] = attrs.item(i).nodeValue; | |
} | |
} | |
} | |
// replace the node with a container | |
container = document.createElement("div"); | |
node.parentNode.insertBefore(container, node); | |
node.parentNode.removeChild(node); | |
// invoke | |
obj = new this.tagRegistry[name](container, attr); | |
}) | |
/** | |
* parse the document | |
* @privileged | |
* @method parse | |
*/ | |
.Method("parse", function() { | |
// collect all tags from the page | |
for (var i = 0, tags = [].slice.apply(LIx.$Tag('li:connect')), len = tags.length; i < len; i++) { | |
this.processTagMatch(tags[i]); | |
} | |
// if using html5 compliant tags | |
if (LIx.ENV.html5) { | |
for (var i = 0, tags = [].slice.apply(LIx.$Tag('embed')), len = tags.length; i < len; i++) { | |
this.processTagMatch(tags[i]); | |
} | |
} | |
}) | |
/** | |
* add a new tag to the parser engine | |
* @privileged | |
* @param name {String} the tag name to handle | |
* @param obj {Object} the object to create for this match | |
* @method add | |
*/ | |
.Method("add", function(name, obj) { | |
this.tagRegistry[name] = obj; | |
}); | |
// auto executing to create a single tp, map the "add" function to it | |
// and then on dom ready trigger a parse | |
(function() { | |
var tp = new LIx.TagParser(); | |
// alias this instance for readability | |
window.LIx.addTag = function() { | |
tp.add.apply(tp, arguments); | |
}; | |
LIx.Event.onDOMReady(function() { | |
tp.parse(); | |
}); | |
})(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment