diff --git a/labs/architecture-examples/cujo/README.md b/labs/architecture-examples/cujo/README.md index 9ac6038f0b..70251c450b 100644 --- a/labs/architecture-examples/cujo/README.md +++ b/labs/architecture-examples/cujo/README.md @@ -1,12 +1,12 @@ -# Cujojs TodoMVC +# cujoJS TodoMVC -[Cujojs](http://cujojs.com) is an *architectural framework* for building highly modular, scalable, maintainable applications in Javascript. It provides architectural plumbing, such as modules (AMD and CommonJS), declarative application composition, declarative connections, and aspect oriented programming. +[cujoJS](http://cujojs.com) is an *architectural framework* for building highly modular, scalable, maintainable applications in Javascript. It provides architectural plumbing, such as modules (AMD and CommonJS), declarative application composition, declarative connections, and aspect oriented programming. It is not a typical MV\* framework, although it does provide MV\* building blocks, such as templating and data binding. ## Highlights: -Some things we feel are interesting about cujojs's TodoMVC as compared to other implementations: +Some things we feel are interesting about cujoJS's TodoMVC as compared to other implementations: * Application composition is separate from application logic * Code is *highly* modular and organized into components, each consisting of diff --git a/labs/architecture-examples/cujo/TODO.md b/labs/architecture-examples/cujo/TODO.md index 740c146e73..924f679081 100644 --- a/labs/architecture-examples/cujo/TODO.md +++ b/labs/architecture-examples/cujo/TODO.md @@ -3,5 +3,3 @@ TODO before release * implement filters (using routing or another method) * build javascript using cram.js -* use curl's preloads feature rather than .next() in run.js -* use a theme.css file diff --git a/labs/architecture-examples/cujo/app/controller.js b/labs/architecture-examples/cujo/app/controller.js index cbfef69bb8..65ef9d44c5 100644 --- a/labs/architecture-examples/cujo/app/controller.js +++ b/labs/architecture-examples/cujo/app/controller.js @@ -2,25 +2,25 @@ define(function () { 'use strict'; - var textProp; + var textProp, updateRemainingCount; /** * Self-optimizing function to set the text of a node */ - var updateRemainingCount = function () { + updateRemainingCount = function (nodes, value) { // sniff for proper textContent property textProp = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; // resume normally updateRemainingCount = setTextProp; - updateRemainingCount(arguments); + updateRemainingCount(nodes, value); }; - var setTextProp = function (nodes, value) { + function setTextProp(nodes, value) { for (var i = 0; i < nodes.length; i++) { nodes[i][textProp] = '' + value; } - }; + } return { /** @@ -84,8 +84,10 @@ define(function () { * Check/uncheck all todos */ toggleAll: function () { - var todos = this.todos; - var complete = this.masterCheckbox.checked; + var todos, complete; + + todos = this.todos; + complete = this.masterCheckbox.checked; todos.forEach(function (todo) { todo.complete = complete; @@ -99,8 +101,10 @@ define(function () { * checked or unchecked. */ updateCount: function () { - var total = 0; - var checked = 0; + var total, checked; + + total = 0; + checked = 0; this.todos.forEach(function (todo) { total++; @@ -128,4 +132,5 @@ define(function () { updateRemainingCount(this.remainingNodes, remaining); } }; + }); diff --git a/labs/architecture-examples/cujo/app/footer/template.html b/labs/architecture-examples/cujo/app/footer/template.html index 0f565fed6e..2338c145fa 100644 --- a/labs/architecture-examples/cujo/app/footer/template.html +++ b/labs/architecture-examples/cujo/app/footer/template.html @@ -1,6 +1,5 @@ diff --git a/labs/architecture-examples/cujo/app/list/template.html b/labs/architecture-examples/cujo/app/list/template.html index f396a889d1..a4b9cbf4b3 100644 --- a/labs/architecture-examples/cujo/app/list/template.html +++ b/labs/architecture-examples/cujo/app/list/template.html @@ -10,7 +10,7 @@ - +
diff --git a/labs/architecture-examples/cujo/app/main.js b/labs/architecture-examples/cujo/app/main.js index 985297b7b0..c256ee2b39 100644 --- a/labs/architecture-examples/cujo/app/main.js +++ b/labs/architecture-examples/cujo/app/main.js @@ -10,8 +10,8 @@ define({ // Render and insert the create view createView: { render: { - template: { module: 'text!create/template.html' }, - replace: { module: 'i18n!create/strings' } + template: { module: 'text!app/create/template.html' }, + replace: { module: 'i18n!app/create/strings' } }, insert: { first: 'root' } }, @@ -26,9 +26,9 @@ define({ // data and mapping data fields to the DOM listView: { render: { - template: { module: 'text!list/template.html' }, - replace: { module: 'i18n!list/strings' }, - css: { module: 'css!list/structure.css' } + template: { module: 'text!app/list/template.html' }, + replace: { module: 'i18n!app/list/strings' }, + css: { module: 'css!app/list/structure.css' } }, insert: { after: 'createView' }, bind: { @@ -38,7 +38,7 @@ define({ text: 'label, .edit', complete: [ '.toggle', - { attr: 'classList', handler: { module: 'list/setCompletedClass' } } + { attr: 'classList', handler: { module: 'app/list/setCompletedClass' } } ] } } @@ -48,9 +48,9 @@ define({ // filters, and clear completed button. controlsView: { render: { - template: { module: 'text!controls/template.html' }, - replace: { module: 'i18n!controls/strings' }, - css: { module: 'css!controls/structure.css' } + template: { module: 'text!app/controls/template.html' }, + replace: { module: 'i18n!app/controls/strings' }, + css: { module: 'css!app/controls/structure.css' } }, insert: { after: 'listView' } }, @@ -59,8 +59,8 @@ define({ // is still fully internationalized. footerView: { render: { - template: { module: 'text!footer/template.html' }, - replace: { module: 'i18n!footer/strings' } + template: { module: 'text!app/footer/template.html' }, + replace: { module: 'i18n!app/footer/strings' } }, insert: { after: 'root' } }, @@ -81,10 +81,10 @@ define({ todos: { create: { - module: 'cola/Hub', + module: 'cola/Collection', args: { strategyOptions: { - validator: { module: 'create/validateTodo' } + validator: { module: 'app/create/validateTodo' } } } }, @@ -100,11 +100,11 @@ define({ // view controllers. Since this is a relatively simple application, // a single controller fits well. todoController: { - prototype: { create: 'controller' }, + create: 'app/controller', properties: { todos: { $ref: 'todos' }, - createTodo: { compose: 'parseForm | todos.add' }, + createTodo: { compose: 'form.getValues | todos.add' }, removeTodo: { compose: 'todos.remove' }, updateTodo: { compose: 'todos.update' }, @@ -123,7 +123,8 @@ define({ 'change:.toggle': 'updateTodo', 'click:#toggle-all': 'toggleAll', 'dblclick:label': 'todos.edit', - 'change,focusout:.edit': 'todos.submit' // also need way to submit on [enter] + 'change,focusout:.edit': 'todos.submit', + 'submit:form': 'todos.submit' }, controlsView: { 'click:#clear-completed': 'removeCompleted' @@ -139,9 +140,9 @@ define({ } }, - parseForm: { module: 'cola/dom/formToObject' }, - cleanTodo: { module: 'create/cleanTodo' }, - generateMetadata: { module: 'create/generateMetadata' }, + form: { module: 'cola/dom/form' }, + cleanTodo: { module: 'app/create/cleanTodo' }, + generateMetadata: { module: 'app/create/generateMetadata' }, toggleEditingState: { create: { diff --git a/labs/architecture-examples/cujo/app/run.js b/labs/architecture-examples/cujo/app/run.js index 64514c132e..2317cddfd1 100644 --- a/labs/architecture-examples/cujo/app/run.js +++ b/labs/architecture-examples/cujo/app/run.js @@ -2,21 +2,20 @@ (function (curl) { 'use strict'; - var config = { - baseUrl: 'app', - paths: { - theme: '../theme', - curl: '../lib/curl/src/curl' - }, - pluginPath: 'curl/plugin', + curl({ + main: 'wire!app/main', packages: [ - { name: 'wire', location: '../lib/wire', main: 'wire' }, - { name: 'when', location: '../lib/when', main: 'when' }, - { name: 'aop', location: '../lib/aop', main: 'aop' }, - { name: 'cola', location: '../lib/cola', main: 'cola' }, - { name: 'poly', location: '../lib/poly', main: 'poly' } - ] - }; + { name: 'curl', location: 'bower_components/curl/src/curl' }, + { name: 'wire', location: 'bower_components/wire', main: 'wire' }, + { name: 'when', location: 'bower_components/when', main: 'when' }, + { name: 'meld', location: 'bower_components/meld', main: 'meld' }, + { name: 'cola', location: 'bower_components/cola', main: 'cola' }, + { name: 'poly', location: 'bower_components/poly', main: 'poly' } + ], + preloads: ['poly/string', 'poly/array'], + // Turn off i18n locale sniffing. Change or remove this line if you want to + // test specific locales or try automatic locale-sniffing. + locale: false + }); - curl(config, ['poly/string', 'poly/array']).next(['wire!main']); })(curl); diff --git a/labs/architecture-examples/cujo/bower.json b/labs/architecture-examples/cujo/bower.json index 70bee78fef..8e79668d6f 100644 --- a/labs/architecture-examples/cujo/bower.json +++ b/labs/architecture-examples/cujo/bower.json @@ -1,12 +1,12 @@ { - "name": "todomvc-cujo", + "name": "todomvc-cujoJS", "version": "0.0.0", "dependencies": { "todomvc-common": "~0.1.4", "curl": "~0.7.3", "cola": "latest", "poly": "~0.5.1", - "when": "~2.0.1", + "when": "~2.1.0", "wire": "~0.9.4", "meld": "~1.3.0" } diff --git a/labs/architecture-examples/cujo/bower_components/cola/.gitignore b/labs/architecture-examples/cujo/bower_components/cola/.gitignore new file mode 100644 index 0000000000..3a8b5bf354 --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/.gitignore @@ -0,0 +1,4 @@ +.idea/ +node_modules +/test/curl +test/util diff --git a/labs/architecture-examples/cujo/bower_components/cola/.gitmodules b/labs/architecture-examples/cujo/bower_components/cola/.gitmodules new file mode 100644 index 0000000000..827cdfeec7 --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/.gitmodules @@ -0,0 +1,9 @@ +[submodule "test/curl"] + path = test/curl + url = https://unscriptable@github.com/cujojs/curl.git +[submodule "test/util"] + path = test/util + url = https://unscriptable@github.com/cujojs/util.git +[submodule "support/when"] + path = support/when + url = https://github.com/cujojs/when.git diff --git a/labs/architecture-examples/cujo/bower_components/cola/Collection.js b/labs/architecture-examples/cujo/bower_components/cola/Collection.js new file mode 100644 index 0000000000..3b3272fe45 --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/Collection.js @@ -0,0 +1,110 @@ +/** + * Collection + */ +(function(define) { +define(function(require) { + + var Base, resolver, eventTypes, simpleStrategy; + + Base = require('./hub/Base'); + resolver = require('./collectionAdapterResolver'); + simpleStrategy = require('./network/strategy/default'); + + eventTypes = extend(Base.prototype.eventTypes, { + // collection item events. most of these come with data. devs can + // decide to use these events for their own purposes or send + // different data than described here, the following list outlines + // the intended behavior. + add: 1, // data == item added + remove: 1, // data == item removed + target: 1, // data == item targeted TODO: rename this to "point"? + // multi-item events + select: 1, // select an item (data == item) + unselect: 1, // deselect an item (data == item) + // batch events + collect: 1, // start of batch mode (until abort or submit) (data = batch purpose) + deliver: 1 // collected items (data = batch purpose with collected items array as property) + }); + + function Collection(options) { + Base.call(this, options); + + if(!options) { + options = {}; + } + + this.strategy = options.strategy; + if (!this.strategy) this.strategy = simpleStrategy(options.strategyOptions); + + } + + Collection.prototype = Object.create(Base.prototype, { + + eventTypes: { value: eventTypes }, + + resolver: { value: resolver }, + + forEach: { + value: function forEach(lambda) { + var provider = this.getProvider(); + return provider && provider.forEach(lambda); + } + }, + + findItem: { + value: function (anything) { + var info = this._findItemFor(anything); + return info && info.item; + } + }, + + findNode: { + value: function (anything) { + var info = this._findNodeFor(anything); + return info && info.node; + } + }, + + getProvider: { + value: function () { + var a, i = this.adapters.length; + while(a = this.adapters[--i]) { + if(a.provide) return a; + } + } + }, + + _findNodeFor: { + value: function (anything) { + var node, i, adapters, adapter; + + adapters = this.adapters; + + // loop through adapters that have the findNode() method + // to try to find out which adapter and which node + i = 0; + while (!node && (adapter = adapters[i++])) { + if (adapter.findNode) { + node = adapter.findNode(anything); + } + } + + return node && { node: node }; + } + } + + }); + + return Collection; + + function extend(base, mixin) { + var extended = Object.create(base); + for(var p in mixin) { + extended[p] = mixin[p]; + } + + return extended; + } + +}); +}(typeof define === 'function' ? define : function(factory) { module.exports = factory(require); })); diff --git a/labs/architecture-examples/cujo/bower_components/cola/Model.js b/labs/architecture-examples/cujo/bower_components/cola/Model.js new file mode 100644 index 0000000000..674c9a3438 --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/Model.js @@ -0,0 +1,34 @@ +/** + * Model + * @author: brian + */ +(function(define) { +define(function(require) { + + var Base, resolver, defaultModelStrategy; + + Base = require('./hub/Base'); + resolver = require('./objectAdapterResolver'); + defaultModelStrategy = require('./network/strategy/defaultModel'); + + function Model(options) { + Base.call(this, options); + + if(!options) { + options = {}; + } + + this.strategy = options.strategy; + if (!this.strategy) this.strategy = defaultModelStrategy(options.strategyOptions); + } + + Model.prototype = Object.create(Base.prototype, { + + resolver: { value: resolver } + + }); + + return Model; + +}); +}(typeof define === 'function' ? define : function(factory) { module.exports = factory(require); })); diff --git a/labs/architecture-examples/cujo/lib/cola/SortedMap.js b/labs/architecture-examples/cujo/bower_components/cola/SortedMap.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/SortedMap.js rename to labs/architecture-examples/cujo/bower_components/cola/SortedMap.js diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/Array.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/Array.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/adapter/Array.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/Array.js diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/LocalStorage.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/LocalStorage.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/adapter/LocalStorage.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/LocalStorage.js diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/Object.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/Object.js similarity index 81% rename from labs/architecture-examples/cujo/lib/cola/adapter/Object.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/Object.js index 046db52c9a..3273da3ea0 100644 --- a/labs/architecture-examples/cujo/lib/cola/adapter/Object.js +++ b/labs/architecture-examples/cujo/bower_components/cola/adapter/Object.js @@ -14,13 +14,23 @@ define(function (require) { */ function ObjectAdapter(obj, options) { + if(!options) { + options = {}; + } + this._obj = obj; this._options = options; + if('provide' in options) { + this.provide = options.provide; + } + } ObjectAdapter.prototype = { + provide: true, + update: function (item) { var self = this; @@ -39,6 +49,18 @@ define(function (require) { }, + properties: function(lambda) { + var self = this; + return when(this._obj, function(obj) { + function properties(l) { + l(obj); + } + self.properties = properties; + + return properties(lambda); + }); + }, + getOptions: function () { return this._options; } @@ -67,4 +89,4 @@ define(function (require) { typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/ObjectToArray.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/ObjectToArray.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/adapter/ObjectToArray.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/ObjectToArray.js diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/Query.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/Query.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/adapter/Query.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/Query.js diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/makeJoined.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/makeJoined.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/adapter/makeJoined.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/makeJoined.js diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/makeTransformed.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/makeTransformed.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/adapter/makeTransformed.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/makeTransformed.js index 0a6d6eab76..9e1a34fe95 100644 --- a/labs/architecture-examples/cujo/lib/cola/adapter/makeTransformed.js +++ b/labs/architecture-examples/cujo/bower_components/cola/adapter/makeTransformed.js @@ -98,4 +98,4 @@ define(function (require) { typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/adapter/makeTransformedProperties.js b/labs/architecture-examples/cujo/bower_components/cola/adapter/makeTransformedProperties.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/adapter/makeTransformedProperties.js rename to labs/architecture-examples/cujo/bower_components/cola/adapter/makeTransformedProperties.js diff --git a/labs/architecture-examples/cujo/bower_components/cola/adapterResolver.js b/labs/architecture-examples/cujo/bower_components/cola/adapterResolver.js new file mode 100644 index 0000000000..9ebfc1312c --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/adapterResolver.js @@ -0,0 +1,43 @@ +(function (define) { +define(function () { +"use strict"; + + return { + /** + * Finds an adapter for the given object and the role. + * This is overly simplistic for now. We can replace this + * resolver later. + * @param object {Object} + * @description Loops through all Adapters registered with + * AdapterResolver.register, calling each Adapter's canHandle + * method. Adapters added later are found first. + */ + resolve: function(object) { + var adapters, i, Adapter; + + adapters = this.adapters; + + if (adapters) { + i = adapters.length; + while ((Adapter = adapters[--i])) { + if (Adapter.canHandle(object)) { + return Adapter; + } + } + } + }, + + register: function(Adapter) { + var adapters = this.adapters; + if(adapters.indexOf(Adapter) === -1) { + adapters.push(Adapter); + } + } + }; + +}); +}( + typeof define == 'function' + ? define + : function (factory) { module.exports = factory(); } +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/bower_components/cola/bower.json b/labs/architecture-examples/cujo/bower_components/cola/bower.json new file mode 100644 index 0000000000..4454dcadcd --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/bower.json @@ -0,0 +1,9 @@ +{ + "name": "cola", + "version": "0.0.0", + "commit": "27b8c7e8fe88feef62a746d29d30af945dcb244d", + "repository": { + "type": "git", + "url": "git://github.com/cujojs/cola" + } +} \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/cola.js b/labs/architecture-examples/cujo/bower_components/cola/cola.js similarity index 83% rename from labs/architecture-examples/cujo/lib/cola/cola.js rename to labs/architecture-examples/cujo/bower_components/cola/cola.js index 388457adc2..bad1abc235 100644 --- a/labs/architecture-examples/cujo/lib/cola/cola.js +++ b/labs/architecture-examples/cujo/bower_components/cola/cola.js @@ -21,9 +21,12 @@ function(when, propertiesKey, byProperty) { defaultQuerySelectorAll = { $ref: 'dom.all!' }; defaultOn = { $ref: 'on!' }; - function initBindOptions(incomingOptions, pluginOptions) { + function initBindOptions(incomingOptions, pluginOptions, resolver) { var options, identifier, comparator; + if(resolver.isRef(incomingOptions)) { + incomingOptions = { to: incomingOptions }; + } options = copyOwnProps(incomingOptions, pluginOptions); if(!options.querySelector) { @@ -56,7 +59,7 @@ function(when, propertiesKey, byProperty) { function doBind(facet, options, wire) { var target = facet.target; - return when(wire(initBindOptions(facet.options, options)), + return when(wire(initBindOptions(facet.options, options, wire.resolver)), function(options) { var to = options.to; if (!to) throw new Error('wire/cola: "to" must be specified'); @@ -78,18 +81,24 @@ function(when, propertiesKey, byProperty) { }; return { - wire$plugin: function(ready, destroyed, pluginOptions) { + wire$plugin: function(pluginOptions) { + + var options, p; - var options = {}; + options = {}; - for(var p in pluginOptions) { - if(!(p in excludeOptions)) { - options[p] = pluginOptions[p]; + if(arguments.length) { + pluginOptions = arguments[arguments.length-1]; + + for(p in pluginOptions) { + if(!(p in excludeOptions)) { + options[p] = pluginOptions[p]; + } } } function bindFacet(resolver, facet, wire) { - when.chain(doBind(facet, options, wire), resolver); + resolver.resolve(doBind(facet, options, wire)); } return { diff --git a/labs/architecture-examples/cujo/bower_components/cola/collectionAdapterResolver.js b/labs/architecture-examples/cujo/bower_components/cola/collectionAdapterResolver.js new file mode 100644 index 0000000000..d94a46735f --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/collectionAdapterResolver.js @@ -0,0 +1,19 @@ +/** + * collectionAdapterResolver + * @author: brian + */ +(function(define) { +define(function(require) { + + var adapterResolver = require('./adapterResolver'); + + return Object.create(adapterResolver, { + adapters: { value: [ + require('./adapter/Array'), + require('./dom/adapter/NodeList'), + require('./adapter/Query') + ]} + }); + +}); +}(typeof define === 'function' ? define : function(factory) { module.exports = factory(require); })); diff --git a/labs/architecture-examples/cujo/lib/cola/comparator/byProperty.js b/labs/architecture-examples/cujo/bower_components/cola/comparator/byProperty.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/comparator/byProperty.js rename to labs/architecture-examples/cujo/bower_components/cola/comparator/byProperty.js index 6de3bcafea..1484ca65f0 100644 --- a/labs/architecture-examples/cujo/lib/cola/comparator/byProperty.js +++ b/labs/architecture-examples/cujo/bower_components/cola/comparator/byProperty.js @@ -19,4 +19,4 @@ define(function (require) { typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/comparator/compose.js b/labs/architecture-examples/cujo/bower_components/cola/comparator/compose.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/comparator/compose.js rename to labs/architecture-examples/cujo/bower_components/cola/comparator/compose.js diff --git a/labs/architecture-examples/cujo/lib/cola/comparator/naturalOrder.js b/labs/architecture-examples/cujo/bower_components/cola/comparator/naturalOrder.js similarity index 98% rename from labs/architecture-examples/cujo/lib/cola/comparator/naturalOrder.js rename to labs/architecture-examples/cujo/bower_components/cola/comparator/naturalOrder.js index f77b96b503..4f2fdff5b2 100644 --- a/labs/architecture-examples/cujo/lib/cola/comparator/naturalOrder.js +++ b/labs/architecture-examples/cujo/bower_components/cola/comparator/naturalOrder.js @@ -15,4 +15,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/comparator/reverse.js b/labs/architecture-examples/cujo/bower_components/cola/comparator/reverse.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/comparator/reverse.js rename to labs/architecture-examples/cujo/bower_components/cola/comparator/reverse.js diff --git a/labs/architecture-examples/cujo/lib/cola/dom/adapter/Node.js b/labs/architecture-examples/cujo/bower_components/cola/dom/adapter/Node.js similarity index 66% rename from labs/architecture-examples/cujo/lib/cola/dom/adapter/Node.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/adapter/Node.js index db4e67bdce..7caefeabde 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/adapter/Node.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/adapter/Node.js @@ -5,9 +5,10 @@ define(function (require) { "use strict"; - var bindingHandler; + var bindingHandler, guess; bindingHandler = require('../bindingHandler'); + guess = require('../guess'); /** * Creates a cola adapter for interacting with dom nodes. Be sure to @@ -21,12 +22,12 @@ define(function (require) { this._rootNode = rootNode; // set options - if (!options.bindings) options.bindings = {}; + options.bindings = guessBindingsFromDom(this._rootNode, options); + this._options = options; this._handlers = {}; - this._createItemToDomHandlers(); - + this._createItemToDomHandlers(options.bindings); } NodeAdapter.prototype = { @@ -51,6 +52,10 @@ define(function (require) { }); }, + properties: function(lambda) { + lambda(this._item); + }, + _itemToDom: function (item, hash) { var p, handler; for (p in hash) { @@ -59,10 +64,9 @@ define(function (require) { } }, - _createItemToDomHandlers: function () { - var bindings, creator; + _createItemToDomHandlers: function (bindings) { + var creator; - bindings = this._options.bindings; creator = bindingHandler(this._rootNode, this._options); Object.keys(bindings).forEach(function (b) { @@ -85,9 +89,32 @@ define(function (require) { return NodeAdapter; + function guessBindingsFromDom(rootNode, options) { + var nodeFinder, nodes, bindings; + + bindings = options.bindings || {}; + nodeFinder = options.nodeFinder || options.querySelectorAll || options.querySelector; + + nodes = nodeFinder('[name],[data-cola-binding]', rootNode); + + if(nodes) { + Array.prototype.forEach.call(nodes, function(n) { + var name, attr; + + attr = n.name ? 'name' : 'data-cola-binding'; + name = guess.getNodePropOrAttr(n, attr); + if(name && !(name in bindings)) { + bindings[name] = '[' + attr + '="' + name + '"]'; + } + }); + } + + return bindings; + } + }); }( typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/dom/adapter/NodeList.js b/labs/architecture-examples/cujo/bower_components/cola/dom/adapter/NodeList.js similarity index 92% rename from labs/architecture-examples/cujo/lib/cola/dom/adapter/NodeList.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/adapter/NodeList.js index 49094473ca..c9809c15d0 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/adapter/NodeList.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/adapter/NodeList.js @@ -4,7 +4,7 @@ define(function(require) { var SortedMap, classList, NodeAdapter, defaultIdAttribute, defaultTemplateSelector, listElementsSelector, - colaListBindingStates, undef; + colaListBindingStates, allBindingStates, undef; SortedMap = require('../../SortedMap'); classList = require('../classList'); @@ -20,12 +20,17 @@ define(function(require) { unbound: 'cola-list-unbound' }; + allBindingStates = Object.keys(colaListBindingStates).map(function(key) { + return colaListBindingStates[key]; + }).join(' '); + /** * Manages a collection of dom trees that are synced with a data * collection. * @constructor * @param rootNode {Node} node to serve as a template for items * in the collection / list. + * @param {object} options * @param options.comparator {Function} comparator function to use for * ordering nodes * @param [options.containerNode] {Node} optional parent to all itemNodes. If @@ -295,14 +300,24 @@ define(function(require) { }, _checkBoundState: function () { - var state, isBound, isEmpty; - state = {}; + var states, isBound, isEmpty; + states = []; isBound = this._itemCount != null; isEmpty = this._itemCount == 0; - state[colaListBindingStates.unbound] = !isBound; - state[colaListBindingStates.empty] = isEmpty; - state[colaListBindingStates.bound] = isBound && !isEmpty; - classList.setClassSet(this._rootNode, state); + + if(!isBound) { + states.push(colaListBindingStates.unbound); + } + + if(isEmpty) { + states.push(colaListBindingStates.empty); + } + + if(isBound && !isEmpty) { + states.push(colaListBindingStates.bound); + } + + setBindingStates(states.join(' '), this._rootNode); } }; @@ -312,6 +327,10 @@ define(function(require) { return obj && obj.tagName && obj.insertBefore && obj.removeChild; }; + function setBindingStates(states, node) { + node.className = classList.addClass(states, classList.removeClass(allBindingStates, node.className)); + } + function findTemplateNode (root, options) { var useBestGuess, node; @@ -343,4 +362,4 @@ define(function(require) { typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/dom/bindingHandler.js b/labs/architecture-examples/cujo/bower_components/cola/dom/bindingHandler.js similarity index 87% rename from labs/architecture-examples/cujo/lib/cola/dom/bindingHandler.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/bindingHandler.js index b7b27140b6..686df2d436 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/bindingHandler.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/bindingHandler.js @@ -2,10 +2,11 @@ define(function (require) { "use strict"; - var slice, guess; + var slice, guess, form; slice = Array.prototype.slice; guess = require('./guess'); + form = require('./form'); defaultNodeHandler.inverse = defaultInverseNodeHandler; @@ -169,20 +170,33 @@ define(function (require) { function defaultNodeHandler (node, data, info) { var attr, value, current; - attr = info.attr || guess.propForNode(node); - value = data[info.prop]; - // always compare first to try to prevent unnecessary IE reflow/repaint - current = guess.getNodePropOrAttr(node, attr); - if (current !== value) { - guess.setNodePropOrAttr(node, attr, value); + if(node.form) { + form.setValues(node.form, data, function(_, name) { + return name === info.prop; + }); + } else { + attr = info.attr || guess.propForNode(node); + value = data[info.prop]; + // always compare first to try to prevent unnecessary IE reflow/repaint + current = guess.getNodePropOrAttr(node, attr); + if (current !== value) { + guess.setNodePropOrAttr(node, attr, value); + } } } function defaultInverseNodeHandler (node, data, info) { var attr, value; - attr = info.attr || guess.propForNode(node); - value = guess.getNodePropOrAttr(node, attr); - data[info.prop] = value; + + if(node.form) { + value = form.getValues(node.form, function(el) { + return el === node || el.name === node.name; + }); + data[info.prop] = value[info.prop]; + } else { + attr = info.attr || guess.propForNode(node); + data[info.prop] = guess.getNodePropOrAttr(node, attr); + } } function createInverseHandler (binding, propToDom) { @@ -215,4 +229,4 @@ define(function (require) { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/dom/classList.js b/labs/architecture-examples/cujo/bower_components/cola/dom/classList.js similarity index 79% rename from labs/architecture-examples/cujo/lib/cola/dom/classList.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/classList.js index 478c0e7988..4780461339 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/classList.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/classList.js @@ -5,6 +5,10 @@ define(function (require, exports) { var splitClassNameRx = /\s+/; + var classRx = '(\\s+|^)(classNames)(\\b(?![\\-_])|$)'; + var trimLeadingRx = /^\s+/; + var splitClassNamesRx = /(\b\s+\b)|(\s+)/g; + /** * Returns the list of class names on a node as an array. * @param node {HTMLElement} @@ -135,7 +139,41 @@ define(function (require, exports) { return str.replace(outerSpacesRx, ''); } + + function addClass (className, str) { + var newClass = removeClass(className, str); + if(newClass && className) { + newClass += ' '; + } + + return newClass + className; + } + + function removeClass (removes, tokens) { + var rx; + + if (!removes) { + return tokens; + } + + // convert space-delimited tokens with bar-delimited (regexp `or`) + removes = removes.replace(splitClassNamesRx, function (m, inner, edge) { + // only replace inner spaces with | + return edge ? '' : '|'; + }); + + // create one-pass regexp + rx = new RegExp(classRx.replace('classNames', removes), 'g'); + + // remove all tokens in one pass (wish we could trim leading + // spaces in the same pass! at least the trim is not a full + // scan of the string) + return tokens.replace(rx, '').replace(trimLeadingRx, ''); + } + return { + addClass: addClass, + removeClass: removeClass, getClassList: getClassList, setClassList: setClassList, getClassSet: getClassSet, diff --git a/labs/architecture-examples/cujo/lib/cola/dom/events.js b/labs/architecture-examples/cujo/bower_components/cola/dom/events.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/dom/events.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/events.js index 8c54053853..5b44213437 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/events.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/events.js @@ -91,4 +91,4 @@ define(function (require) { : function (factory) { module.exports = factory(require); }, this, this.document -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/bower_components/cola/dom/form.js b/labs/architecture-examples/cujo/bower_components/cola/dom/form.js new file mode 100644 index 0000000000..d3b6b071e0 --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/form.js @@ -0,0 +1,200 @@ +/** @license MIT License (c) copyright B Cavalier & J Hann */ + +(function (define) { +define(function () { + + var forEach, slice; + + forEach = Array.prototype.forEach; + slice = Array.prototype.slice; + + return { + getValues: formToObject, + getMultiSelectValue: getMultiSelectValue, + setValues: objectToForm, + setElementValue: setElementValue, + setGroupValue: setGroupValue, + setMultiSelectValue: setMultiSelectValue, + isCheckable: isCheckable + }; + + function objectToForm(form, object, filter) { + var els; + + els = form.elements; + if(typeof filter !== 'function') { + filter = alwaysInclude; + } + + Object.keys(object).forEach(function(name) { + + var el, value; + + value = object[name]; + el = els[name]; + + if(!filter(el, name, value)) return; + + if(el.length) { + setGroupValue(el, value); + } else { + setElementValue(el, value); + } + + }); + + return form; + } + + function setGroupValue(group, value) { + var getBooleanValue; + + getBooleanValue = Array.isArray(value) + ? function(array, el) { return array.indexOf(el.value) >= 0; } + : function(value, el) { return el.value == value; }; + + forEach.call(group, function(el, i) { + if(isCheckable(el)) { + el.checked = getBooleanValue(value, el); + } else { + el.value = textValue(value[i]); + } + }); + } + + function setElementValue(el, value) { + + if(isCheckable(el)) { + + el.checked = !!value; + + } else if(el.multiple && el.options) { + + if(!Array.isArray(value)) { + el.value = textValue(value); + } else { + setMultiSelectValue(el, value); + } + + } else { + el.value = textValue(value); + } + } + + function setMultiSelectValue(select, values) { + var i, option, options; + options = select.options; + i = 0; + while ((option = options[i++])) { + if(values.indexOf(option.value) >= 0) { + option.selected = true; + } + } + } + + function textValue(value) { + return value == null ? '' : value; + } + + function isCheckable(el) { + return el.type == 'radio' || el.type == 'checkbox'; + } + + /** + * Simple routine to pull input values out of a form. + * @param form {HTMLFormElement} + * @return {Object} populated object + */ + function formToObject (formOrEvent, filter) { + var obj, form, els, seen, i, el, name, value; + + form = formOrEvent.selectorTarget || formOrEvent.target || formOrEvent; + + if(typeof filter !== 'function') { + filter = alwaysInclude; + } + + obj = {}; + + els = form.elements; + seen = {}; // finds checkbox groups + i = 0; + + while ((el = els[i++])) { + name = el.name; + // skip over non-named elements and fieldsets (that have no value) + if (!name || !('value' in el) || !filter(el)) continue; + + value = el.value; + + if (el.type == 'radio') { + // only grab one radio value (to ensure that the property + // is always set, we set false if none are checked) + if (el.checked) obj[name] = value; + else if (!(name in seen)) obj[name] = false; + } + else if (el.type == 'checkbox') { + if (!(name in seen)) { + // we're going against normal form convention by ensuring + // the object always has a property of the given name. + // forms would normally not submit a checkbox if it isn't + // checked. + // Note: IE6&7 don't support el.hasAttribute() so we're using el.attributes[] + obj[name] = el.attributes['value'] ? !!el.checked && value : !!el.checked; + } + else if (el.checked) { + // collect checkbox groups into an array. + // if we found a false value, none have been checked so far + obj[name] = (name in obj && obj[name] !== false) + ? [].concat(obj[name], value) + : [value]; + } + } + else if (el.type == 'file') { + if (!(name in seen)) { + obj[name] = getFileInputValue(el); + } + } + else if (el.multiple && el.options) { + // grab all selected options + obj[name] = getMultiSelectValue(el); + } + else { + obj[name] = value; + } + + seen[name] = name; + } + + return obj; + } + + function getFileInputValue (fileInput) { + if ('files' in fileInput) { + return fileInput.multiple ? slice.call(fileInput.files) : fileInput.files[0]; + } else { + return fileInput.value; + } + } + + function getMultiSelectValue (select) { + var values, options, i, option; + values = []; + options = select.options; + i = 0; + while ((option = options[i++])) { + if (option.selected) values.push(option.value); + } + return values; + } + + function alwaysInclude() { + return true; + } + +}); +}( + typeof define == 'function' && define.amd + ? define + : function (factory) { module.exports = factory(); } +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/dom/formElementFinder.js b/labs/architecture-examples/cujo/bower_components/cola/dom/formElementFinder.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/dom/formElementFinder.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/formElementFinder.js index ac3c43f224..f5e4a656a0 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/formElementFinder.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/formElementFinder.js @@ -22,4 +22,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/dom/guess.js b/labs/architecture-examples/cujo/bower_components/cola/dom/guess.js similarity index 97% rename from labs/architecture-examples/cujo/lib/cola/dom/guess.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/guess.js index 277f67be60..040b8f877d 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/guess.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/guess.js @@ -54,9 +54,9 @@ define(function (require) { if (Array.isArray(node)) { // get unique list of events return node.reduce(function (events, node) { - return guessEventsFor(node).filter(function (event) { + return events.concat(guessEventsFor(node).filter(function (event) { return event && events.indexOf(event) < 0; - }) + })); },[]); } else if (isFormValueNode(node)) { @@ -148,4 +148,4 @@ define(function (require) { typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/dom/has.js b/labs/architecture-examples/cujo/bower_components/cola/dom/has.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/dom/has.js rename to labs/architecture-examples/cujo/bower_components/cola/dom/has.js index 2562b06e36..99ddb4bd51 100644 --- a/labs/architecture-examples/cujo/lib/cola/dom/has.js +++ b/labs/architecture-examples/cujo/bower_components/cola/dom/has.js @@ -29,4 +29,4 @@ define(function () { : function (factory) { module.exports = factory(); }, this, this.document -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/enqueue.js b/labs/architecture-examples/cujo/bower_components/cola/enqueue.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/enqueue.js rename to labs/architecture-examples/cujo/bower_components/cola/enqueue.js diff --git a/labs/architecture-examples/cujo/bower_components/cola/hub/Base.js b/labs/architecture-examples/cujo/bower_components/cola/hub/Base.js new file mode 100644 index 0000000000..1d6ef811da --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/hub/Base.js @@ -0,0 +1,334 @@ +/** + * base + * @author: brian + */ +(function(define) { +define(function(require) { + + var when, baseEvents, eventProcessor, simpleStrategy, defaultIdentifier, + beforePhase, propagatingPhase, afterPhase, canceledPhase, + undef; + + when = require('when'); + eventProcessor = require('./eventProcessor'); + simpleStrategy = require('../network/strategy/default'); + defaultIdentifier = require('../identifier/default'); + + // TODO: make these configurable/extensible + baseEvents = { + // basic item events. most of these come with data. devs can + // decide to use these events for their own purposes or send + // different data than described here, the following list outlines + // the intended behavior. + update: 1, // data == item updated + change: 1, // data == event type that caused the change + validate: 1, // data == validation result object with at least a boolean valid prop + // mode events + abort: 1, // abort the current mode (no data) + submit: 1, // finalize the current mode (no data) + // edit event + edit: 1, // enter edit mode (data == item to edit) + // network-level events (not to be used by adapters) + join: 1, // an adapter has joined (data == adapter) + sync: 1, // adapters need to sync (data == boolean. true == provider) + leave: 1 // an adapter has left (data == adapter) + }; + + /** + * Signal that event has not yet been pushed onto the network. + * Return false to prevent the event from being pushed. + */ + beforePhase = {}; + + /** + * Signal that event is currently being propagated to adapters. + */ + propagatingPhase = {}; + + /** + * Signal that an event has already been pushed onto the network. + * Return value is ignored since the event has already propagated. + */ + afterPhase = {}; + + /** + * Signal that an event was canceled and not pushed onto the network. + * Return value is ignored since the event has already propagated. + */ + canceledPhase = {}; + + function BaseHub(options) { + var eventTypes, t; + + this.adapters = []; + + if (!options) options = {}; + + this.identifier = options.identifier || defaultIdentifier; + + this.eventProcessor = Object.create(eventProcessor, { + queue: { value: [] }, + eventProcessor: { value: this.processEvent.bind(this) } + }); + + eventTypes = this.eventTypes; + for(t in eventTypes) { + this.addApi(t); + } + } + + BaseHub.prototype = { + + eventTypes: baseEvents, + + dispatchEvent: function (name, data) { + try { + return this[name](data); + } + catch (ex) { + // TODO: do something with this exception + return false; + } + }, + + createAdapter: function (source, options) { + var Adapter = this.resolver.resolve(source); + return Adapter ? new Adapter(source, options) : source; + }, + + addSource: function (source, options) { + var adapter, proxy; + + if (!options) options = {}; + + if (!options.identifier) options.identifier = this.identifier; + + // create an adapter for this source + adapter = this.createAdapter(source, options); + proxy = this._createAdapterProxy(adapter, options); + proxy.origSource = source; + + // save the proxied adapter + this.adapters.push(proxy); + + this.eventProcessor.processEvent(proxy, null, 'join'); + + return adapter; + }, + + /* + 1. call events.beforeXXX(data) + 2. call strategy on each source/dest pair w/ event XXX and data + - cancel iteration if any strategy returns false for any pair + 3. if not canceled, call events.XXX(data) + */ + processEvent: function (source, data, type) { + var context, strategyApi, self, strategy, adapters; + + context = {}; + self = this; + strategy = this.strategy; + adapters = this.adapters; + + return when( + self.dispatchEvent(eventProcessor.makeBeforeEventName(type), data) + ).then( + function (result) { + context.canceled = result === false; + if (context.canceled) return when.reject(context); + + context.phase = beforePhase; + strategyApi = createStrategyApi(context, self.eventProcessor); + + return strategy(source, undef, data, type, strategyApi); + } + ).then( + function () { + context.phase = propagatingPhase; + return when.map(adapters, function (adapter) { + if (source != adapter) { + return strategy(source, adapter, data, type, strategyApi); + } + }); + } + ).then( + function () { + context.phase = context.canceled + ? canceledPhase + : afterPhase; + return strategy(source, undef, data, type, strategyApi); + } + ).then( + function (result) { + context.canceled = result === false; + if (context.canceled) return when.reject(context); + + return self.dispatchEvent(eventProcessor.makeEventName(type), data); + } + ).then( + function () { + return context; + } + ); + }, + + destroy: function () { + var adapters, adapter; + + adapters = this.adapters; + + while ((adapter = adapters.pop())) { + if (typeof adapter.destroy == 'function') { + adapter.destroy(); + } + } + }, + + addApi: function (name) { + this._addApiMethod(name); + this._addApiEvent(name); + }, + + _createAdapterProxy: function (adapter, options) { + var eventFinder, name, method, proxy; + + proxy = Object.create(adapter); + + // keep copy of original source so we can match it up later + if('provide' in options) { + proxy.provide = options.provide; + } + + // sniff for event hooks + eventFinder = this.configureEventFinder(options.eventNames); + + // override methods that require event hooks + for (name in adapter) { + method = adapter[name]; + if (typeof method == 'function' && eventFinder(name)) { + // store original method on proxy (to stop recursion) + proxy[name] = callOriginalMethod(adapter, method); + // change public api of adapter to call back into hub + observeMethod(this.eventProcessor, adapter, name, method); + // ensure hub has a public method of the same name + this.addApi(name); + } + } + + return proxy; + }, + + configureEventFinder: function (option) { + var eventTypes = this.eventTypes; + return typeof option == 'function' + ? option + : function (name) { return name in eventTypes; }; + }, + + _addApiMethod: function (name) { + var adapters, self, eventProcessor; + + adapters = this.adapters; + eventProcessor = this.eventProcessor; + self = this; + + if (!this[name]) { + this[name] = function (anything) { + var sourceInfo; + + sourceInfo = self._findItemFor(anything); + + if(!sourceInfo) { + sourceInfo = { + item: anything, + source: findAdapterForSource(arguments[1], adapters) + }; + } + + return eventProcessor.queueEvent(sourceInfo.source, sourceInfo.item, name); + }; + } + }, + + _addApiEvent: function (name) { + var eventName = this.eventProcessor.makeEventName(name); + // add function stub to api + if (!this[eventName]) { + this[eventName] = function (data) {}; + } + // add beforeXXX stub, too + eventName = this.eventProcessor.makeBeforeEventName(name); + if (!this[eventName]) { + this[eventName] = function (data) {}; + } + }, + + _findItemFor: function (anything) { + var item, i, adapters, adapter; + + adapters = this.adapters; + + // loop through adapters that have the getItemForEvent() method + // to try to find out which adapter and which data item + i = 0; + while (!item && (adapter = adapters[i++])) { + if (adapter.findItem) { + item = adapter.findItem(anything); + } + } + + return item && { item: item }; + } + }; + + return BaseHub; + + function createStrategyApi (context, eventProcessor) { + return { + queueEvent: function(source, data, type) { + return eventProcessor.queueEvent(source, data, type); + }, + cancel: function () { context.canceled = true; }, + isCanceled: function () { return !!context.canceled; }, + handle: function () { context.handled = true; }, + isHandled: function () { return !!context.handled; }, + isBefore: function () { return isPhase(beforePhase); }, + isAfter: function () { return isPhase(afterPhase); }, + isAfterCanceled: function () { return isPhase(canceledPhase); }, + isPropagating: function () { return isPhase(propagatingPhase); } + }; + + function isPhase (phase) { + return context.phase == phase; + } + } + + function callOriginalMethod (adapter, orig) { + return function () { + return orig.apply(adapter, arguments); + }; + } + + function observeMethod (queue, adapter, type, origMethod) { + return adapter[type] = function (data) { + queue.queueEvent(adapter, data, type); + return origMethod.call(adapter, data); + }; + } + + function findAdapterForSource (source, adapters) { + var i, adapter, found; + + // loop through adapters and find which one was created for this source + i = 0; + while (!found && (adapter = adapters[i++])) { + if (adapter.origSource == source) { + found = adapter; + } + } + + return found; + } + +}); +}(typeof define === 'function' ? define : function(factory) { module.exports = factory(require); })); diff --git a/labs/architecture-examples/cujo/bower_components/cola/hub/eventProcessor.js b/labs/architecture-examples/cujo/bower_components/cola/hub/eventProcessor.js new file mode 100644 index 0000000000..3c46bc55d5 --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/hub/eventProcessor.js @@ -0,0 +1,90 @@ +/** + * eventQueue + * @author: brian + */ +(function(define) { +define(function(require) { + + var when, enqueue; + + when = require('when'); + enqueue = require('../enqueue'); + + return { + + makeBeforeEventName: function (name) { + return makeEventName('before', name); + }, + + makeEventName: function(name) { + return makeEventName('on', name); + }, + + /** + * Queue an event for processing later + * @param source + * @param data + * @param type + */ + queueEvent: function (source, data, type) { + // if queue length is zero, we need to start processing it again + var queueNeedsRestart = this.queue.length == 0; + + // enqueue event + this.queue.push({ source: source, data: data, type: type }); + + // start processing, if necessary + return queueNeedsRestart && this._dispatchNextEvent(); + }, + + /** + * Process an event immediately + * @param source + * @param data + * @param type + */ + processEvent: function(source, data, type) { + var self = this; + + this.inflight = when(this.inflight).always(function() { + return self.eventProcessor(source, data, type); + }); + + return this.inflight; + }, + + _dispatchNextEvent: function () { + var event, remaining, deferred, self; + + self = this; + + // get the next event, if any + event = this.queue.shift(); + remaining = this.queue.length; + + // Ensure resolution is next turn, even if no event + // is actually dispatched. + deferred = when.defer(); + enqueue(function () { + var inflight = event && self.processEvent(event.source, event.data, event.type); + deferred.resolve(inflight); + }); + + // Only continue processing the queue if it's not empty + if(remaining) { + deferred.promise.always(function() { + self._dispatchNextEvent(); + }); + } + + return deferred.promise; + + } + }; + + function makeEventName (prefix, name) { + return prefix + name.charAt(0).toUpperCase() + name.substr(1); + } + +}); +}(typeof define === 'function' ? define : function(factory) { module.exports = factory(require); })); diff --git a/labs/architecture-examples/cujo/lib/cola/identifier/default.js b/labs/architecture-examples/cujo/bower_components/cola/identifier/default.js similarity index 98% rename from labs/architecture-examples/cujo/lib/cola/identifier/default.js rename to labs/architecture-examples/cujo/bower_components/cola/identifier/default.js index 7c7f3c4177..3abe6a286f 100644 --- a/labs/architecture-examples/cujo/lib/cola/identifier/default.js +++ b/labs/architecture-examples/cujo/bower_components/cola/identifier/default.js @@ -13,4 +13,4 @@ define(function (require) { typeof define == 'function' ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/identifier/property.js b/labs/architecture-examples/cujo/bower_components/cola/identifier/property.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/identifier/property.js rename to labs/architecture-examples/cujo/bower_components/cola/identifier/property.js index 85fa892224..3ecf66cb0e 100644 --- a/labs/architecture-examples/cujo/lib/cola/identifier/property.js +++ b/labs/architecture-examples/cujo/bower_components/cola/identifier/property.js @@ -21,4 +21,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/base.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/base.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/base.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/base.js index c5c9e774d2..a647124c8b 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/base.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/base.js @@ -26,4 +26,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/changeEvent.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/changeEvent.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/changeEvent.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/changeEvent.js index 0550838d17..78ee2c3108 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/changeEvent.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/changeEvent.js @@ -33,4 +33,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/collectThenDeliver.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/collectThenDeliver.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/collectThenDeliver.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/collectThenDeliver.js index 076ba824c7..4645e6c125 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/collectThenDeliver.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/collectThenDeliver.js @@ -139,4 +139,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/compose.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/compose.js similarity index 87% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/compose.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/compose.js index d1ea67089f..734d857f97 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/compose.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/compose.js @@ -16,7 +16,7 @@ define(function (require) { return function composeStrategies (strategies) { return function (source, dest, data, type, api) { - when.reduce(strategies, + return when.reduce(strategies, function(result, strategy) { var strategyResult = strategy(source, dest, data, type, api); return api.isCanceled() @@ -24,15 +24,19 @@ define(function (require) { : strategyResult; }, data - ).always(function(result) { return result }); + ).then(propagateSuccess, propagateSuccess); } }; + function propagateSuccess(x) { + return x; + } + }); }( typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/default.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/default.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/default.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/default.js index cdf1aa8b6c..46538482ae 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/default.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/default.js @@ -47,4 +47,4 @@ define(function (require) { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/bower_components/cola/network/strategy/defaultModel.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/defaultModel.js new file mode 100644 index 0000000000..43d376e4dc --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/defaultModel.js @@ -0,0 +1,52 @@ +(function (define) { +define(function (require) { + "use strict"; + + // Note: browser loaders and builders require that we don't "meta-program" + // the require() calls: + var compose, base, syncAfterJoin, syncModel, validate, changeEvent; + + compose = require('./compose'); + base = require('./base'); + syncAfterJoin = require('./syncAfterJoin'); + syncModel = require('./syncModel'); + validate = require('./validate'); + changeEvent = require('./changeEvent'); + + /** + * This is a composition of the strategies that Brian and I think + * make sense. :) + * + * @param options {Object} a conglomeration of all of the options for the + * strategies used. + * @param options.targetFirstItem {Boolean} if truthy, the strategy + * will automatically target the first item that is added to the network. + * If falsey, it will not automatically target. + * @param options.validator {Function} if provided, will be used + * to validate data items on add and update events + * + * @return {Function} a composite network strategy function + */ + return function (options) { + + // compose them + return compose([ + // Validate should be early so it can cancel other events + // when validation fails + validate(options), + // Change event support should be earlier than sync events + // so that it can translate them + changeEvent(options), + syncAfterJoin(options), + syncModel(options), + base(options) + ]); + + }; + +}); +}( + typeof define == 'function' && define.amd + ? define + : function (factory) { module.exports = factory(require); } +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/minimal.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/minimal.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/minimal.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/minimal.js index d6ea703c62..f1c2cfb739 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/minimal.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/minimal.js @@ -47,4 +47,4 @@ define(function (require) { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/syncAfterJoin.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncAfterJoin.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/syncAfterJoin.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncAfterJoin.js index 8fda0ba7d3..d186c236e4 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/syncAfterJoin.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncAfterJoin.js @@ -49,4 +49,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/syncDataDirectly.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncDataDirectly.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/syncDataDirectly.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncDataDirectly.js index 6408a4b7e8..096add85ac 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/syncDataDirectly.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncDataDirectly.js @@ -112,4 +112,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncModel.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncModel.js new file mode 100644 index 0000000000..c5d4ab7dad --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/syncModel.js @@ -0,0 +1,115 @@ +(function (define) { + define(function () { + "use strict"; + + /** + * Creates a strategy to push all data from a source into the consumers + * in the network directly (rather than as a sequence of 'add' events + * in the network) when a sync event happens. + * + * @description This strategy helps eliminate loops and complexities + * when data providers and consumers are added at unpredictable times. + * During a sync, all 'add' events are squelched while providers push + * all items to all consumers. + * + * @param [options.providersAreConsumers] {Boolean} if truthy, providers + * are also treated as consumers and receive items from other providers. + * @return {Function} a network strategy function + */ + return function (options) { + var synced, providers, consumers, undef; + + if (!options) options = {}; + + // TODO: consider putting these on the api object so they can be shared across strategies + // a list of all known providers and consumers + // these lists tend to be very small + providers = []; + consumers = []; + // the adapter currently being synced + synced = undef; + + return function syncDataDirectly (source, dest, provide, type, api) { + // this strategy stops sync events before going on the network + if ('sync' == type && api.isBefore()) { + synced = source; + try { + if (provide) { + // provide data onto consumers in network + if (typeof source.properties != 'function') { + throw new Error('syncModel: provider doesn\'t have `properties()`.'); + } + // keep track of providers + add(providers, synced); + // also add to consumers list, if specified + if (options.providersAreConsumers) { + add(consumers, synced); + } + // push data to all consumers + forEach(consumers, function (consumer) { + source.properties(function (item) { + consumer.update(item); + }); + }); + } + else { + // keep track of consumers + add(consumers, synced); + // provide data onto consumers in network + if (typeof source.update == 'function') { + // consume data from all providers + forEach(providers, function (provider) { + provider.properties(function (item) { + synced.update(item); + }); + }); + } + } + // the sync event never gets onto the network: + api.cancel(); + } + finally { + synced = undef; + } + } + // stop 'add' events between adapters while sync'ing, but allow + // strategies interested in the event to see it before + else if ('add' == type && synced && !api.isBefore()) { + api.cancel(); + } + // keep track of adapters that leave + else if ('leave' == type && api.isAfter()) { + // these just end up being noops if the source isn't in the list + remove(providers, source); + remove(consumers, source); + } + }; + + function add (list, adapter) { + list.push(adapter); + } + + function remove (list, adapter) { + forEach(list, function (provider, i , providers) { + if (provider == adapter) { + providers.splice(i, 1); + } + }); + } + + function forEach (list, lambda) { + var i, obj; + i = list.length; + while ((obj = list[--i])) { + lambda(obj, i, list); + } + } + + }; + + }); +}( + typeof define == 'function' && define.amd + ? define + : function (factory) { module.exports = factory(); } + )); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/targetFirstItem.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/targetFirstItem.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/targetFirstItem.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/targetFirstItem.js index 59d6c10e23..f6988a303a 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/targetFirstItem.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/targetFirstItem.js @@ -31,4 +31,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/network/strategy/validate.js b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/validate.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/network/strategy/validate.js rename to labs/architecture-examples/cujo/bower_components/cola/network/strategy/validate.js index 0f949f75ee..07ea2c7945 100644 --- a/labs/architecture-examples/cujo/lib/cola/network/strategy/validate.js +++ b/labs/architecture-examples/cujo/bower_components/cola/network/strategy/validate.js @@ -37,4 +37,4 @@ define(function () { typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/bower_components/cola/objectAdapterResolver.js b/labs/architecture-examples/cujo/bower_components/cola/objectAdapterResolver.js new file mode 100644 index 0000000000..8445240b7c --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/cola/objectAdapterResolver.js @@ -0,0 +1,18 @@ +/** + * objectAdapterResolver + * @author: brian + */ +(function(define) { +define(function(require) { + + var adapterResolver = require('./adapterResolver'); + + return Object.create(adapterResolver, { + adapters: { value: [ + require('./dom/adapter/Node'), + require('./adapter/Object') + ]} + }); + +}); +}(typeof define === 'function' ? define : function(factory) { module.exports = factory(require); })); diff --git a/labs/architecture-examples/cujo/lib/cola/projection/assign.js b/labs/architecture-examples/cujo/bower_components/cola/projection/assign.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/projection/assign.js rename to labs/architecture-examples/cujo/bower_components/cola/projection/assign.js index 90ac3cc50d..ab42eb3fd5 100644 --- a/labs/architecture-examples/cujo/lib/cola/projection/assign.js +++ b/labs/architecture-examples/cujo/bower_components/cola/projection/assign.js @@ -29,4 +29,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/projection/inherit.js b/labs/architecture-examples/cujo/bower_components/cola/projection/inherit.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/projection/inherit.js rename to labs/architecture-examples/cujo/bower_components/cola/projection/inherit.js index 49c78f5c52..ffdf624668 100644 --- a/labs/architecture-examples/cujo/lib/cola/projection/inherit.js +++ b/labs/architecture-examples/cujo/bower_components/cola/projection/inherit.js @@ -33,4 +33,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/relational/hashJoin.js b/labs/architecture-examples/cujo/bower_components/cola/relational/hashJoin.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/relational/hashJoin.js rename to labs/architecture-examples/cujo/bower_components/cola/relational/hashJoin.js diff --git a/labs/architecture-examples/cujo/lib/cola/relational/propertiesKey.js b/labs/architecture-examples/cujo/bower_components/cola/relational/propertiesKey.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/relational/propertiesKey.js rename to labs/architecture-examples/cujo/bower_components/cola/relational/propertiesKey.js index 36287deec5..0c58760c82 100644 --- a/labs/architecture-examples/cujo/lib/cola/relational/propertiesKey.js +++ b/labs/architecture-examples/cujo/bower_components/cola/relational/propertiesKey.js @@ -47,4 +47,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/relational/strategy/leftOuterJoin.js b/labs/architecture-examples/cujo/bower_components/cola/relational/strategy/leftOuterJoin.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/relational/strategy/leftOuterJoin.js rename to labs/architecture-examples/cujo/bower_components/cola/relational/strategy/leftOuterJoin.js diff --git a/labs/architecture-examples/cujo/lib/cola/transform/compose.js b/labs/architecture-examples/cujo/bower_components/cola/transform/compose.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/transform/compose.js rename to labs/architecture-examples/cujo/bower_components/cola/transform/compose.js diff --git a/labs/architecture-examples/cujo/lib/cola/transform/configure.js b/labs/architecture-examples/cujo/bower_components/cola/transform/configure.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/transform/configure.js rename to labs/architecture-examples/cujo/bower_components/cola/transform/configure.js index 36ddb244da..d8fd7615a7 100644 --- a/labs/architecture-examples/cujo/lib/cola/transform/configure.js +++ b/labs/architecture-examples/cujo/bower_components/cola/transform/configure.js @@ -33,4 +33,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/transform/createEnum.js b/labs/architecture-examples/cujo/bower_components/cola/transform/createEnum.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/transform/createEnum.js rename to labs/architecture-examples/cujo/bower_components/cola/transform/createEnum.js index 8f9326f6c4..557c35182a 100644 --- a/labs/architecture-examples/cujo/lib/cola/transform/createEnum.js +++ b/labs/architecture-examples/cujo/bower_components/cola/transform/createEnum.js @@ -142,4 +142,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/transform/expression.js b/labs/architecture-examples/cujo/bower_components/cola/transform/expression.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/transform/expression.js rename to labs/architecture-examples/cujo/bower_components/cola/transform/expression.js index a5c90d8035..0530c1101f 100644 --- a/labs/architecture-examples/cujo/lib/cola/transform/expression.js +++ b/labs/architecture-examples/cujo/bower_components/cola/transform/expression.js @@ -33,4 +33,4 @@ define(function () { // string because of "oddities" between `eval` and `this`. return eval('' + this); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/validation/composeValidators.js b/labs/architecture-examples/cujo/bower_components/cola/validation/composeValidators.js similarity index 99% rename from labs/architecture-examples/cujo/lib/cola/validation/composeValidators.js rename to labs/architecture-examples/cujo/bower_components/cola/validation/composeValidators.js index ff981857f4..63d86ed7f7 100644 --- a/labs/architecture-examples/cujo/lib/cola/validation/composeValidators.js +++ b/labs/architecture-examples/cujo/bower_components/cola/validation/composeValidators.js @@ -49,4 +49,4 @@ define(function () { typeof define == 'function' ? define : function (factory) { module.exports = factory(); } -)); +)); \ No newline at end of file diff --git a/labs/architecture-examples/cujo/lib/cola/validation/form/formValidationHandler.js b/labs/architecture-examples/cujo/bower_components/cola/validation/form/formValidationHandler.js similarity index 100% rename from labs/architecture-examples/cujo/lib/cola/validation/form/formValidationHandler.js rename to labs/architecture-examples/cujo/bower_components/cola/validation/form/formValidationHandler.js diff --git a/labs/architecture-examples/cujo/lib/curl/.gitmodules b/labs/architecture-examples/cujo/bower_components/curl/.gitmodules similarity index 100% rename from labs/architecture-examples/cujo/lib/curl/.gitmodules rename to labs/architecture-examples/cujo/bower_components/curl/.gitmodules diff --git a/labs/architecture-examples/cujo/bower_components/curl/bower.json b/labs/architecture-examples/cujo/bower_components/curl/bower.json new file mode 100644 index 0000000000..0a8f45c43d --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/curl/bower.json @@ -0,0 +1,8 @@ +{ + "name": "curl", + "version": "0.7.3", + "repository": { + "type": "git", + "url": "git://github.com/cujojs/curl" + } +} \ No newline at end of file diff --git a/labs/architecture-examples/cujo/bower_components/curl/package.json b/labs/architecture-examples/cujo/bower_components/curl/package.json new file mode 100644 index 0000000000..3498e8fc2a --- /dev/null +++ b/labs/architecture-examples/cujo/bower_components/curl/package.json @@ -0,0 +1,39 @@ +{ + "name": "curl", + "version": "0.7.3", + "description": "A small, fast module and resource loader with dependency management. (AMD, CommonJS Modules/1.1, CSS, HTML, etc.)", + "keywords": ["curl", "cujo", "amd", "loader", "module"], + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/mit-license.php" + } + ], + "repositories": [ + { + "type": "git", + "url": "https://github.com/cujojs/curl" + } + ], + "bugs": "https://github.com/cujojs/curl/issues", + "maintainers": [ + { + "name": "John Hann", + "web": "http://unscriptable.com" + } + ], + "contributors": [ + { + "name": "John Hann", + "web": "http://unscriptable.com" + }, + { + "name": "Brian Cavalier", + "web": "http://hovercraftstudios.com" + } + ], + "main": "./src/curl", + "directories": { + "test": "test" + } +} diff --git a/labs/architecture-examples/cujo/lib/curl/src/curl.js b/labs/architecture-examples/cujo/bower_components/curl/src/curl.js similarity index 63% rename from labs/architecture-examples/cujo/lib/curl/src/curl.js rename to labs/architecture-examples/cujo/bower_components/curl/src/curl.js index a5ca3a55d1..d19ced37e2 100644 --- a/labs/architecture-examples/cujo/lib/curl/src/curl.js +++ b/labs/architecture-examples/cujo/bower_components/curl/src/curl.js @@ -9,42 +9,46 @@ * Licensed under the MIT License at: * http://www.opensource.org/licenses/mit-license.php * - * @version 0.6.6 */ (function (global) { //"use strict"; don't restore this until the config routine is refactored var - version = '0.6.6', + version = '0.7.3', curlName = 'curl', - userCfg = global[curlName], + defineName = 'define', + userCfg, prevCurl, prevDefine, doc = global.document, head = doc && (doc['head'] || doc.getElementsByTagName('head')[0]), + // to keep IE from crying, we need to put scripts before any + //