Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Inviz/93023 to your computer and use it in GitHub Desktop.

Select an option

Save Inviz/93023 to your computer and use it in GitHub Desktop.
(function() {
var $base = '/javascripts/';
var $extend = function(one, another){
if (!one) one = {};
if (!another) another = {};
for (var i in another) {
if (typeof one[i] == "object" && !one[i].push && !one[i].appendChild) {
if (!one[i]) one[i] = {}
$extend(one[i], another[i]);
} else {
one[i] = another[i];
}
}
return one;
};
var Chain = function() {
this.$chain = []
};
Chain.prototype = {
chain: function(){
for (var i = 0, j = arguments.length; i < j; i++) this.$chain.push(arguments[i])
return this;
},
callChain: function(){
return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
},
clearChain: function(){
this.$chain = [];
return this;
}
};
DependencyManager = function(doc) {
DependencyManager.instance = this;
this.document = doc || document;
if (!DependencyManager.tree) DependencyManager.tree = {};
if (!DependencyManager.flat) DependencyManager.flat = {};
if (!DependencyManager.expanded) DependencyManager.expanded = {};
this.queue = [];
this.loaded = [];
this.loading = {};
return this;
};
var Request = function(url, onComplete) {
this.transport = this.getTransport();
this.request(url);
this.onComplete = onComplete
};
Request.prototype = {
request: function(url) {
this.transport.open("get", url, true);
var self = this
this.transport.onreadystatechange = function() { self.onStateChange.apply(self, arguments) }
this.transport.send("");
},
getTransport: function() {
if (window.ActiveXObject) return new ActiveXObject('Microsoft.XMLHTTP');
else if (window.XMLHttpRequest) return new XMLHttpRequest();
else return false;
},
onStateChange: function() {
if (this.transport.readyState == 4 && this.transport.status == 200) {
var self = this
if (this.onComplete) setTimeout(function(){self.onComplete(self.transport);}, 10);
this.transport.onreadystatechange = function(){};
}
}
};
DependencyManager.fetch = function(path) {
if (!path) path = 'scripts.json';
new Request($base + path, function(xhr) {
var text = xhr.responseText;
eval("DependencyManager.instance.register(" + text + ")");
var instance = DependencyManager.instance
instance.initialized = true;
if (instance && instance.queue.length) for (var i = 0, j = instance.queue.length; i < j; i++) instance.queue[i]();
//if (text.match(/^\s*\{.*?\}\s*$/m)) eval(test)
//else console.log ('bad scripts.json')
})
};
DependencyManager.javascript = function(source, properties) {
properties = $extend({
onload: function() {},
document: document,
check: function() { return true }
}, properties);
var doc = properties.document, script = doc.createElement('script');
script.onload = properties.onload;
script.onreadystatechange = function() {
var state = this.readyState;
if ("loaded" === state || "complete" === state) {
script.onreadystatechange = null;
properties.onload();
}
};
//do we care of Safari 2.x?
script.src = source;
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
return script
};
DependencyManager.prototype = {
using: function() {
var args = [];
for (var i = 0, j = arguments.length; i < j; i++) {
if (arguments[i].push) for (var k = 0, l = arguments[i].length; k < l; k++) args.push(arguments[i][k])
else args.push(arguments[i]);
}
var callback = (typeof args[args.length - 1] == "function") && args.pop();
var self = this;
var setup = function() { return self.setup(args, callback); };
if (!args.length && callback) return callback();
if (this.initialized) {
return setup();
} else {
if (this.queue.indexOf(setup) == -1) this.queue.push(setup);
}
},
register: function(tree) {
if (!tree) return;
$extend(DependencyManager.tree, tree);
this.flatten();
},
setup: function(args, callback) {
var files = [], thread = new Chain;
for (var i = 0, j = args.length; i < j; i++) {
var expanded = this.expand(args[i]);
if (typeof expanded == "object" && expanded.push) {
for (var k = 0, l = expanded.length; k < l; k++) files.push(expanded[k]);
} else {
files.push(expanded);
}
}
var self = this;
for (var i = 0, j = files.length; i < j; i++) {
(function(file) { //lol
thread.chain(function() {
self.load(file, thread);
});
})(files[i]);
}
if (callback) thread.chain(function() {
setTimeout(callback, 10)
});
thread.callChain();
return this;
},
expand: function(name, prefix) {
if (!prefix && typeof(name) == "object") {
prefix = name.prefix
name = name.name
}
var prefixed = name + (prefix || "");
if (DependencyManager.expanded[prefixed]) return DependencyManager.expanded[prefixed];
var files = [];
var file = this.browse(name, prefix);
if (file && file.deps) {
for (var i = 0, j = file.deps.length; i < j; i++) {
var deps = this.expand(file.deps[i], file.prefix);
for (var k = 0, l = deps.length; k < l; k++) files.push(deps[k]);
}
}
if (file) files.push(file);
if (!DependencyManager.expanded[prefixed]) DependencyManager.expanded[prefixed] = files;
return files;
},
flatten: function(node, prefix) {
var result = DependencyManager.flat;
if (!node) node = DependencyManager.tree;
if (!prefix) prefix = '';
for (var i in node) {
var path = prefix ? prefix + '/' + i : i;
var file = node[i];
if (file.desc) {
if (!DependencyManager.flat[path]) {
DependencyManager.flat[path] = file = $extend({
path: path,
name: i,
id: i.split('.').pop(),
prefix: prefix || ''
}, node[i]);
}
result[path] = file;
} else if (typeof file == 'object' && !file.push) { //simple object? Dive deeply
DependencyManager.flat = $extend(DependencyManager.flat, this.flatten(file, path))
} else { //string or array? it's file definition
return file
}
}
return result;
},
browse: function(name, prefix) {
var result, bits = prefix && prefix.length ? prefix.split('/') : []
bits.push(name);
while(bits.length > 0) {
var str = bits.join("/");
bits.shift();
if (str.length && (result = this.find(str))) return result;
}
bits = prefix && prefix.length ? prefix.split('/') : []
while(bits.length > 0) {
var str = bits.join("/");
bits.shift();
if (str.length && (result = this.grep(str))) return result;
}
return false;
},
find: function(name) {
return this.grep(new RegExp(name + "(?:\.js)?$", "i"))[0];
},
grep: function(regex, deep) {
if (!regex.source) regex = new RegExp(regex + "/(?:" + (deep ? "." : "[^/]") + ")+$", "i");
var match = [];
for (var i in DependencyManager.flat) if (i.match(regex)) match.push(DependencyManager.flat[i]);
return match;
},
load: function(file, thread) {
if (this.loaded.indexOf(file.path) > -1) {
thread.callChain();
} else if (this.loading[file.path]) {
var active = this.loading[file.path];
active.$chain.unshift(function() {
thread.callChain();
active.callChain();
})
} else {
var self = this;
this.loading[file.path] = thread;
return DependencyManager.javascript($base + file.path + ".js" + (location.search.indexOf('NOCACHE') == -1 ? ("?" + Math.random()) : ""), {
onload: function() {
console.info('Now using', file.path, "(" + file.desc + ")");
delete self.loading[file.path];
self.loaded.push(file.path);
if (thread) thread.callChain();
},
document: this.document
})
}
}
}
})();
$dependencies = new DependencyManager
DependencyManager.fetch()
function using() {
$dependencies.using.apply($dependencies, arguments);
};
(function() {
Behavioured = {
behaviourise: function(object) {
var result = []
this.Behaviour.each(function(file) {
if (!file.rule) return;
var decision;
switch ($type(object)) {
case "element":
decision = (file.rule == true) ? object.hasClass(file.id.toLowerCase()) : (object.match(file.rule) || object.getElement(file.rule));
break;
case "object": case "hash":
decision = Hash.get(object, file.id);
}
if (!decision) return;
result.push(file);
}, this)
return result;
},
Behaviour: [],
Traits: new Hash
};
Traits = $merge({
create: function(a,b,c,d,e) {
var params = Array.link(arguments, {files: Array.type, element: Element.type});
var traits = this.behaviourise(params.element || params.options);
var chain = new Chain;
var opts = $merge(this.prototype.options)
if (params.files) {
traits.each(function(trait) {
opts[trait.id] = trait;
});
};
(function() {;
using(traits, function() {
var klass = new Class({Extends: this, options: opts});
traits.each(function(trait) {
var mixin = this.Traits[trait.id] || this.Base.Traits[trait.id];
if (!mixin) throw Error("Trait named " + trait.id + " is not preset");
opts = $merge(mixin.prototype.options, opts);
klass.inherit(mixin);
}, this);
klass.prototype.options = opts;
var instance = new klass(a, b, c, d, e);
console.log('Created', instance, 'of', klass, 'for', params.element, 'traits are', traits);
chain.callChain(instance);
}.bind(this));
}).delay(10, this);
return chain;
},
of: function(path) {
return $merge(this, {Behaviour: DependencyManager.instance.grep(path + '/Traits')});
}
}, Behavioured)
Types = $merge({
create: function(a,b,c,d,e) {
var params = Array.link(arguments, {options: Object.type, element: Element.type});
var candidates = this.behaviourise(params.element || params.options);
var candidate = candidates[0];
if (candidate) {
using(candidate.path, function() {
var klass = this[candidate.id];
klass.Base = this; //make subclass aware of parent
klass.create(a,b,c,d,e);
}.bind(this));
} else {
new this(a,b,c,d,e);
}
},
of: function(path) {
return $merge(this, {Behaviour: DependencyManager.instance.grep(path)});
},
}, Behavioured);
})();
{
"Library": {
"Inflections": {
"desc": "A library that adds pluralizing/singularizing capabilities to String objects."
},
"Mimeparse": {
"desc": "A library to parse/negotiate mime-types and ranges in JavaScript."
},
"Color": {
"desc": "Brings advanced HSB coloring to mootools."
},
"Crypto": {
"MD5": {
"desc": "Adds MD5 hashing functions."
},
"SHA1": {
"desc": "Adds SHA1 encoding functions."
}
}
},
"Fx": {
"Fx.ProgressBar": {
"desc": "Contains logic for animated progress bars."
}
},
"Widget": {
"Autocompleter": {
"Autocompleter": {
"desc": "Contains basic autocompleting features."
},
"Autocompleter.Ext": {
"deps": ["Autocompleter"],
"desc": "Functions to attach autocompleter on form fields."
},
"Autocompleter.Remote": {
"deps": ["Autocompleter"],
"desc": "Autocompleter extensions to recieve suggestions via XHR."
},
"Autocompleter.Local": {
"deps": ["Autocompleter"],
"desc": "Adds local storage suggesting capabilities."
}
},
"Uploader": {
"Uploader": {
"deps": ["Uploader.Swiff"],
"desc": "Extendable flash uploader control."
},
"Uploader.Swiff": {
"desc": "The interface to flash uploader"
},
"Uploader.Block": {
"deps": ["Uploader"],
"desc": "Contains tools to build large uploader widget."
},
"Uploader.Input": {
"deps": ["Uploader"],
"desc": "Contains tools to build small in-place file input field."
},
"Traits": {
"Progressing": {
"desc": "Additional functions to create progress bars."
},
"Sensitive": {
"desc": "Creates a confirmation dialog when user attempts to cancel upload."
},
"Stateful": {
"desc": "Some eye candy for browse button (propagates mousedown events through flash layer)"
},
"Singular": {
"deps": ["Progressing"],
"desc": "An extension to Progressing trait for progress bars on file fields."
}
}
},
"Canvas": {
"Canvas": {
"desc": "Contains tools to create animated sliding content canvas."
},
"Traits": {
"Nested": {
"deps": ["Canvas"],
"desc": "Contains logic to resolve conflicts between nested canvases."
},
"Historical": {
"deps": ["Canvas", "History"],
"desc": "Each page slide of given canvas will be noted in browser history."
}
}
},
"Tabs": {
"Tabs": {
"desc": "Clickable tabs that display certain part of preloaded content."
},
"Tabs.Sliding": {
"desc": "Contains logic to combine sliding canvas and tabs features together.",
"rule": true
},
"Traits": {
"Animated": {
"desc": "Adds a cute little effect that slides triangle pointing to currently active tab.",
"rule": true
}
}
},
"History": {
"desc": "Tools to create new items in browser history and to track URL state changes."
},
"SortableTable": {
"desc": "Contains functions to make tables sortable for users by clicking on headings."
},
"Calendar": {
"desc": "Simple popup date-picker calendar to be assign on inputs or as buttons."
},
"Textarea.Grow": {
"desc": "Textarea grows as you type."
},
"MooSwitch": {
"desc": "Iphone-like switch binary control."
},
"Orwik": {
"Followship": {
"desc": "Simple controller to handle follow/unfollow kind of button set."
},
"InviteBox": {
"deps": ["Autocompleter.Ext"],
"desc": "Invite one person or many people at once in a widget."
},
"Categories": {
"desc": "Simple widget to add new categories to the list using form."
}
}
},
"Page": {
"Feed": {
"deps": ["Calendar"],
"desc": "Ready setup for scrollable and paginated event feed."
},
"PDFViewer": {
"deps": ["Swiff"],
"desc": "Flash based tool to browse large images like converted PDF documents."
},
"Dashboard": {
"desc": "Pretty cool widget board engine."
},
"Portal": {
"desc": "Accommodates Dashboard, Canvas, Tabs and a few other widgets together."
},
"Chat": {
"desc": "Jabber chat application. Currently frozen."
},
"Comments": {
"desc": "A page with comments to write, view or manage."
},
"Discussions": {
"deps": ["Comments"],
"desc": "Extended version of comments with quote support."
},
"Memberships": {
"deps": ["Sortables.Sensitive"],
"desc": "A page to add or manage memberships in different permission groups."
},
"Authorships": {
"desc": "A page to manage and reorder authors in horizontal list."
},
"Browser": {
"Core": {
"Browser": {
"desc": "Multicolumned document browser that works over json."
},
"Integrations": {
"desc": "Contains logic to assign and load other widgets to be used in document browser."
},
"Layout": {
"desc": "Contains table layout and column classes."
}
},
"Fancy": {
"Browser": {
"deps": ["Helpers", "Effects", "Layout", "Integrations", "Tools"],
"desc": "Fancy file browser with all the animations and cool ajaxy features."
},
"Integrations": {
"desc": "Integrates uploader, sliding canvas, sortable table and more."
},
"Helpers": {
"desc": "Contains helpers to build document browser markup."
},
"Effects": {
"desc": "Now browsing between columns is fun because of sliding animation."
},
"Layout": {
"desc": "More column logic for all the fancyness."
}
}
}
},
"Form": {
"Form": {
"desc": "Extendable multipurpose form"
},
"Traits": {
"Asynchronous": {
"desc": "Makes form submission asynchronous, so user does not navigate away.",
"rule": "form.traited"
},
"Validated": {
"deps": ["Element.Tip", "Inflections"],
"desc": "Form expects BadRequest server JSON response to display errors on certain fields.",
"rule": true
},
"Reusable": {
"desc": "Form gets reset on successfull submission for later reuse.",
"rule": "form[empty]"
},
"Multivariant": {
"desc": "Adds capabilities to display a widget to select some items or all of them in one click.",
"rule": "div.variants"
},
"Multimodel": {
"desc": "Adds support for some nested parts of a form to be cloned and reused for multi-model forms",
"rule": "div.clonable"
},
"Growing": {
"deps": ["Textarea.Grow"],
"desc": "Textareas in given form will expand as you type avoiding scroll bar appearance.",
"rule": "textarea"
},
"Uploading": {
"deps": ["Uploader"],
"desc": "Form has file input to handle",
"rule": "input[type=file]"
}
}
},
"Element": {
"Tip": {
"desc": "Add a floating message that points on specific element."
}
},
"Sortables": {
"Sortables.Extended": {
"desc": "Custom build of Sortables with more events."
},
"Sortables.Sensitive": {
"deps": ["Sortables.Extended", "Jester"],
"desc": "User should confirm each time he reorders the items."
}
},
"Request": {
"Jester": {
"deps": ["Inflections"],
"desc": "REST-wrapper to manage resources asynchronously."
},
"Socket": {
"deps": ["Swiff"],
"desc": "Flash socket client wrapper for persistent connections"
}
},
"Application": {
"Application": {
"desc": "A tool to create sandboxed applications in on-screen windows."
},
"Tools": {
"deps": ["Mimeparse", "Tools.Registered"],
"desc": "Work with applications without loading any interface dependencies."
},
"Tools.Registered": {
"desc": "Contains installed applications definitions. May be served from smart backend."
}
},
"Canvas": {
"Moo": {
"desc": "Moo canvas by ibolmo. Lean, but doesnt have all the features."
},
"Ex": {
"desc": "Excanvas by google. More weight comes with more functionality."
}
}
}
Tabs.Sliding = new Class({
Extends: Tabs,
options: {
container: null
},
initialize: function(tabs, pages, options) {
var wrapper = options.container ? $(options.container).getElement('.canvas-wrapper') : pages.getParent('.canvas-wrapper')
SlidingCanvas.create(wrapper, pages, {
onSet: this.setActive.bind(this)
}).chain(function(canvas) {
this.slider = canvas
}.bind(this))
this.parent(tabs, pages, options)
},
setActive: function(tab) {
this.parent(tab)
if (this.slider) this.slider.set(this.tabs.getChildren().indexOf(this.parent(tab)))
}
});
Tabs.Sliding.extend(Traits.of('Widget/Tabs'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment