From db69b6edb53322c615d54cdfc047342caf46a41b Mon Sep 17 00:00:00 2001 From: Nick Comer Date: Mon, 15 Jul 2013 23:03:03 -0400 Subject: [PATCH] Updating stapes to version 0.8.0 --- ajax/libs/stapes/0.8.0/stapes.js | 594 +++++++++++++++++++++++++++ ajax/libs/stapes/0.8.0/stapes.min.js | 2 + ajax/libs/stapes/package.json | 2 +- 3 files changed, 597 insertions(+), 1 deletion(-) create mode 100644 ajax/libs/stapes/0.8.0/stapes.js create mode 100644 ajax/libs/stapes/0.8.0/stapes.min.js diff --git a/ajax/libs/stapes/0.8.0/stapes.js b/ajax/libs/stapes/0.8.0/stapes.js new file mode 100644 index 000000000..106af1716 --- /dev/null +++ b/ajax/libs/stapes/0.8.0/stapes.js @@ -0,0 +1,594 @@ +// +// ____ _ _ +// / ___|| |_ __ _ _ __ ___ ___ (_)___ (*) +// \___ \| __/ _` | '_ \ / _ \/ __| | / __| +// ___) | || (_| | |_) | __/\__ \_ | \__ \ +// |____/ \__\__,_| .__/ \___||___(_)/ |___/ +// |_| |__/ +// +// (*) a (really) tiny Javascript MVC microframework +// +// (c) Hay Kranen < hay@bykr.org > +// Released under the terms of the MIT license +// < http://en.wikipedia.org/wiki/MIT_License > +// +// Stapes.js : http://hay.github.com/stapes +(function() { + 'use strict'; + + var VERSION = "0.8.0"; + + // Global counter for all events in all modules (including mixed in objects) + var guid = 1; + + // Makes _.create() faster + if (!Object.create) { + var CachedFunction = function(){}; + } + + // So we can use slice.call for arguments later on + var slice = Array.prototype.slice; + + // Private attributes and helper functions, stored in an object so they + // are overwritable by plugins + var _ = { + // Properties + attributes : {}, + + eventHandlers : { + "-1" : {} // '-1' is used for the global event handling + }, + + guid : -1, + + // Methods + addEvent : function(event) { + // If we don't have any handlers for this type of event, add a new + // array we can use to push new handlers + if (!_.eventHandlers[event.guid][event.type]) { + _.eventHandlers[event.guid][event.type] = []; + } + + // Push an event object + _.eventHandlers[event.guid][event.type].push({ + "guid" : event.guid, + "handler" : event.handler, + "scope" : event.scope, + "type" : event.type + }); + }, + + addEventHandler : function(argTypeOrMap, argHandlerOrScope, argScope) { + var eventMap = {}, + scope; + + if (typeof argTypeOrMap === "string") { + scope = argScope || false; + eventMap[ argTypeOrMap ] = argHandlerOrScope; + } else { + scope = argHandlerOrScope || false; + eventMap = argTypeOrMap; + } + + for (var eventString in eventMap) { + var handler = eventMap[eventString]; + var events = eventString.split(" "); + + for (var i = 0, l = events.length; i < l; i++) { + var eventType = events[i]; + _.addEvent.call(this, { + "guid" : this._guid || this._.guid, + "handler" : handler, + "scope" : scope, + "type" : eventType + }); + } + } + }, + + addGuid : function(object, forceGuid) { + if (object._guid && !forceGuid) return; + + object._guid = guid++; + + _.attributes[object._guid] = {}; + _.eventHandlers[object._guid] = {}; + }, + + // This is a really small utility function to save typing and produce + // better optimized code + attr : function(guid) { + return _.attributes[guid]; + }, + + clone : function(obj) { + var type = _.typeOf(obj); + + if (type === 'object') { + return _.extend({}, obj); + } + + if (type === 'array') { + return obj.slice(0); + } + }, + + create : function(proto) { + if (Object.create) { + return Object.create(proto); + } else { + CachedFunction.prototype = proto; + return new CachedFunction(); + } + }, + + createSubclass : function(props, includeEvents) { + props = props || {}; + includeEvents = includeEvents || false; + + var superclass = props.superclass.prototype; + + // Objects always have a constructor, so we need to be sure this is + // a property instead of something from the prototype + var realConstructor = props.hasOwnProperty('constructor') ? props.constructor : function(){}; + + function constructor() { + // Be kind to people forgetting new + if (!(this instanceof constructor)) { + throw new Error("Please use 'new' when initializing Stapes classes"); + } + + // If this class has events add a GUID as well + if (this.on) { + _.addGuid( this, true ); + } + + realConstructor.apply(this, arguments); + } + + if (includeEvents) { + _.extend(superclass, Events); + } + + constructor.prototype = _.create(superclass); + constructor.prototype.constructor = constructor; + + _.extend(constructor, { + extend : function() { + return _.extendThis.apply(this, arguments); + }, + + // We can't call this 'super' because that's a reserved keyword + // and fails in IE8 + 'parent' : superclass, + + proto : function() { + return _.extendThis.apply(this.prototype, arguments); + }, + + subclass : function(obj) { + obj = obj || {}; + obj.superclass = this; + return _.createSubclass(obj); + } + }); + + // Copy all props given in the definition to the prototype + for (var key in props) { + if (key !== 'constructor' && key !== 'superclass') { + constructor.prototype[key] = props[key]; + } + } + + return constructor; + }, + + emitEvents : function(type, data, explicitType, explicitGuid) { + explicitType = explicitType || false; + explicitGuid = explicitGuid || this._guid; + + // #30: make a local copy of handlers to prevent problems with + // unbinding the event while unwinding the loop + var handlers = slice.call(_.eventHandlers[explicitGuid][type]); + + for (var i = 0, l = handlers.length; i < l; i++) { + // Clone the event to prevent issue #19 + var event = _.extend({}, handlers[i]); + var scope = (event.scope) ? event.scope : this; + + if (explicitType) { + event.type = explicitType; + } + + event.scope = scope; + event.handler.call(event.scope, data, event); + } + }, + + // Extend an object with more objects + extend : function() { + var args = slice.call(arguments); + var object = args.shift(); + + for (var i = 0, l = args.length; i < l; i++) { + var props = args[i]; + for (var key in props) { + object[key] = props[key]; + } + } + + return object; + }, + + // The same as extend, but uses the this value as the scope + extendThis : function() { + var args = slice.call(arguments); + args.unshift(this); + return _.extend.apply(this, args); + }, + + // from http://stackoverflow.com/a/2117523/152809 + makeUuid : function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); + }, + + removeAttribute : function(keys, silent) { + silent = silent || false; + + // Split the key, maybe we want to remove more than one item + var attributes = _.trim(keys).split(" "); + + // Actually delete the item + for (var i = 0, l = attributes.length; i < l; i++) { + var key = _.trim(attributes[i]); + + if (key) { + delete _.attr(this._guid)[key]; + + // If 'silent' is set, do not throw any events + if (!silent) { + this.emit('change', key); + this.emit('change:' + key); + this.emit('remove', key); + this.emit('remove:' + key); + } + } + } + }, + + removeEventHandler : function(type, handler) { + var handlers = _.eventHandlers[this._guid]; + + if (type && handler) { + // Remove a specific handler + handlers = handlers[type]; + if (!handlers) return; + + for (var i = 0, l = handlers.length, h; i < l; i++) { + h = handlers[i].handler; + if (h && h === handler) { + handlers.splice(i--, 1); + l--; + } + } + } else if (type) { + // Remove all handlers for a specific type + delete handlers[type]; + } else { + // Remove all handlers for this module + _.eventHandlers[this._guid] = {}; + } + }, + + setAttribute : function(key, value, silent) { + silent = silent || false; + + // We need to do this before we actually add the item :) + var itemExists = this.has(key); + var oldValue = _.attr(this._guid)[key]; + + // Is the value different than the oldValue? If not, ignore this call + if (value === oldValue) { + return; + } + + // Actually add the item to the attributes + _.attr(this._guid)[key] = value; + + // If 'silent' flag is set, do not throw any events + if (silent) { + return; + } + + // Throw a generic event + this.emit('change', key); + + // And a namespaced event as well, NOTE that we pass value instead of + // key here! + this.emit('change:' + key, value); + + // Throw namespaced and non-namespaced 'mutate' events as well with + // the old value data as well and some extra metadata such as the key + var mutateData = { + "key" : key, + "newValue" : value, + "oldValue" : oldValue || null + }; + + this.emit('mutate', mutateData); + this.emit('mutate:' + key, mutateData); + + // Also throw a specific event for this type of set + var specificEvent = itemExists ? 'update' : 'create'; + + this.emit(specificEvent, key); + + // And a namespaced event as well, NOTE that we pass value instead of key + this.emit(specificEvent + ':' + key, value); + }, + + trim : function(str) { + return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + }, + + typeOf : function(val) { + if (val === null || typeof val === "undefined") { + // This is a special exception for IE, in other browsers the + // method below works all the time + return String(val); + } else { + return Object.prototype.toString.call(val).replace(/\[object |\]/g, '').toLowerCase(); + } + }, + + updateAttribute : function(key, fn, silent) { + var item = this.get(key); + + // In previous versions of Stapes we didn't have the check for object, + // but still this worked. In 0.7.0 it suddenly doesn't work anymore and + // we need the check. Why? I have no clue. + var type = _.typeOf(item); + + if (type === 'object' || type === 'array') { + item = _.clone(item); + } + + var newValue = fn.call(this, item, key); + _.setAttribute.call(this, key, newValue, silent || false); + } + }; + + // Can be mixed in later using Stapes.mixinEvents(object); + var Events = { + emit : function(types, data) { + data = (typeof data === "undefined") ? null : data; + + var splittedTypes = types.split(" "); + + for (var i = 0, l = splittedTypes.length; i < l; i++) { + var type = splittedTypes[i]; + + // First 'all' type events: is there an 'all' handler in the + // global stack? + if (_.eventHandlers[-1].all) { + _.emitEvents.call(this, "all", data, type, -1); + } + + // Catch all events for this type? + if (_.eventHandlers[-1][type]) { + _.emitEvents.call(this, type, data, type, -1); + } + + if (typeof this._guid === 'number') { + // 'all' event for this specific module? + if (_.eventHandlers[this._guid].all) { + _.emitEvents.call(this, "all", data, type); + } + + // Finally, normal events :) + if (_.eventHandlers[this._guid][type]) { + _.emitEvents.call(this, type, data); + } + } + } + }, + + off : function() { + _.removeEventHandler.apply(this, arguments); + }, + + on : function() { + _.addEventHandler.apply(this, arguments); + } + }; + + _.Module = function() { + + }; + + _.Module.prototype = { + each : function(fn, ctx) { + var attr = _.attr(this._guid); + for (var key in attr) { + var value = attr[key]; + fn.call(ctx || this, value, key); + } + }, + + extend : function() { + return _.extendThis.apply(this, arguments); + }, + + filter : function(fn) { + var filtered = []; + var attributes = _.attr(this._guid); + + for (var key in attributes) { + if ( fn.call(this, attributes[key], key)) { + filtered.push( attributes[key] ); + } + } + + return filtered; + }, + + get : function(input) { + if (typeof input === "string") { + return this.has(input) ? _.attr(this._guid)[input] : null; + } else if (typeof input === "function") { + var items = this.filter(input); + return (items.length) ? items[0] : null; + } + }, + + getAll : function() { + return _.clone( _.attr(this._guid) ); + }, + + getAllAsArray : function() { + var arr = []; + var attributes = _.attr(this._guid); + + for (var key in attributes) { + var value = attributes[key]; + + if (_.typeOf(value) === "object" && !value.id) { + value.id = key; + } + + arr.push(value); + } + + return arr; + }, + + has : function(key) { + return (typeof _.attr(this._guid)[key] !== "undefined"); + }, + + map : function(fn, ctx) { + var mapped = []; + this.each(function(value, key) { + mapped.push( fn.call(ctx || this, value, key) ); + }, ctx || this); + return mapped; + }, + + // Akin to set(), but makes a unique id + push : function(input, silent) { + if (_.typeOf(input) === "array") { + for (var i = 0, l = input.length; i < l; i++) { + _.setAttribute.call(this, _.makeUuid(), input[i], silent || false); + } + } else { + _.setAttribute.call(this, _.makeUuid(), input, silent || false); + } + + return this; + }, + + remove : function(input, silent) { + if (typeof input === 'undefined') { + // With no arguments, remove deletes all attributes + _.attributes[this._guid] = {}; + this.emit('change remove'); + } else if (typeof input === "function") { + this.each(function(item, key) { + if (input(item)) { + _.removeAttribute.call(this, key, silent); + } + }); + } else { + // nb: checking for exists happens in removeAttribute + _.removeAttribute.call(this, input, silent || false); + } + + return this; + }, + + set : function(objOrKey, valueOrSilent, silent) { + if (typeof objOrKey === "object") { + for (var key in objOrKey) { + _.setAttribute.call(this, key, objOrKey[key], valueOrSilent || false); + } + } else { + _.setAttribute.call(this, objOrKey, valueOrSilent, silent || false); + } + + return this; + }, + + size : function() { + var size = 0; + var attr = _.attr(this._guid); + + for (var key in attr) { + size++; + } + + return size; + }, + + update : function(keyOrFn, fn, silent) { + if (typeof keyOrFn === "string") { + _.updateAttribute.call(this, keyOrFn, fn, silent || false); + } else if (typeof keyOrFn === "function") { + this.each(function(value, key) { + _.updateAttribute.call(this, key, keyOrFn); + }); + } + + return this; + } + }; + + var Stapes = { + "_" : _, // private helper functions and properties + + "extend" : function() { + return _.extendThis.apply(_.Module.prototype, arguments); + }, + + "mixinEvents" : function(obj) { + obj = obj || {}; + + _.addGuid(obj); + + return _.extend(obj, Events); + }, + + "on" : function() { + _.addEventHandler.apply(this, arguments); + }, + + "subclass" : function(obj, classOnly) { + classOnly = classOnly || false; + obj = obj || {}; + obj.superclass = classOnly ? function(){} : _.Module; + return _.createSubclass(obj, !classOnly); + }, + + "version" : VERSION + }; + + // This library can be used as an AMD module, a Node.js module, or an + // old fashioned global + if (typeof exports !== "undefined") { + // Server + if (typeof module !== "undefined" && module.exports) { + exports = module.exports = Stapes; + } + exports.Stapes = Stapes; + } else if (typeof define === "function" && define.amd) { + // AMD + define(function() { + return Stapes; + }); + } else { + // Global scope + window.Stapes = Stapes; + } +})(); diff --git a/ajax/libs/stapes/0.8.0/stapes.min.js b/ajax/libs/stapes/0.8.0/stapes.min.js new file mode 100644 index 000000000..7aeb5c26f --- /dev/null +++ b/ajax/libs/stapes/0.8.0/stapes.min.js @@ -0,0 +1,2 @@ +/*! Stapes.js v0.8.0 < http://hay.github.com/stapes > */ +(function(){"use strict";var a="0.8.0",b=1;if(!Object.create)var c=function(){};var d=Array.prototype.slice,e={attributes:{},eventHandlers:{"-1":{}},guid:-1,addEvent:function(a){e.eventHandlers[a.guid][a.type]||(e.eventHandlers[a.guid][a.type]=[]),e.eventHandlers[a.guid][a.type].push({guid:a.guid,handler:a.handler,scope:a.scope,type:a.type})},addEventHandler:function(a,b,c){var d={},f;typeof a=="string"?(f=c||!1,d[a]=b):(f=b||!1,d=a);for(var g in d){var h=d[g],i=g.split(" ");for(var j=0,k=i.length;j