+ {{{github}}}
+
+
+
\ No newline at end of file
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/assets/index.css b/dashboard/04_composite_mojits/mojits/FooterMojit/assets/index.css
new file mode 100755
index 0000000..1cd5114
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/assets/index.css
@@ -0,0 +1,2 @@
+dt { font-weight: bold; }
+.sel { background-color: #FF4; }
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/binders/index.js b/dashboard/04_composite_mojits/mojits/FooterMojit/binders/index.js
new file mode 100755
index 0000000..6162901
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/binders/index.js
@@ -0,0 +1,54 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('FooterMojitBinderIndex', function(Y, NAME) {
+
+/**
+ * The FooterMojitBinderIndex module.
+ *
+ * @module FooterMojitBinderIndex
+ */
+
+ /**
+ * Constructor for the FooterMojitBinderIndex class.
+ *
+ * @class FooterMojitBinderIndex
+ * @constructor
+ */
+ Y.namespace('mojito.binders')[NAME] = {
+
+ /**
+ * Binder initialization method, invoked after all binders on the page
+ * have been constructed.
+ */
+ init: function(mojitProxy) {
+ this.mojitProxy = mojitProxy;
+ },
+
+ /**
+ * The binder method, invoked to allow the mojit to attach DOM event
+ * handlers.
+ *
+ * @param node {Node} The DOM node to which this mojit is attached.
+ */
+ bind: function(node) {
+ var me = this;
+ this.node = node;
+ /**
+ * Example code for the bind method:
+ *
+ * node.all('dt').on('mouseenter', function(evt) {
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).addClass('sel');
+ *
+ * });
+ * node.all('dt').on('mouseleave', function(evt) {
+ *
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).removeClass('sel');
+ *
+ * });
+ */
+ }
+
+ };
+
+}, '0.0.1', {requires: ['event-mouseenter', 'mojito-client']});
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/controller.server.js b/dashboard/04_composite_mojits/mojits/FooterMojit/controller.server.js
new file mode 100755
index 0000000..d148c51
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/controller.server.js
@@ -0,0 +1,32 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('FooterMojit', function(Y, NAME) {
+
+/**
+ * The FooterMojit module.
+ *
+ * @module FooterMojit
+ */
+
+ /**
+ * Constructor for the Controller class.
+ *
+ * @class Controller
+ * @constructor
+ */
+ Y.namespace('mojito.controllers')[NAME] = {
+
+ /**
+ * Method corresponding to the 'index' action.
+ *
+ * @param ac {Object} The ActionContext that provides access
+ * to the Mojito API.
+ */
+ index: function(ac) {
+ ac.done({
+ title: "Copyright 2013 Yahoo! Inc."
+ });
+ }
+
+ };
+
+}, '0.0.1', {requires: ['mojito']});
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/definition.json b/dashboard/04_composite_mojits/mojits/FooterMojit/definition.json
new file mode 100755
index 0000000..470db80
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/definition.json
@@ -0,0 +1,5 @@
+[
+ {
+ "settings": [ "master" ]
+ }
+]
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/models/foo.server.js b/dashboard/04_composite_mojits/mojits/FooterMojit/models/foo.server.js
new file mode 100755
index 0000000..50c0efa
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/models/foo.server.js
@@ -0,0 +1,34 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('FooterMojitModelFoo', function(Y, NAME) {
+
+/**
+ * The FooterMojitModelFoo module.
+ *
+ * @module FooterMojit
+ */
+
+ /**
+ * Constructor for the FooterMojitModelFoo class.
+ *
+ * @class FooterMojitModelFoo
+ * @constructor
+ */
+ Y.namespace('mojito.models')[NAME] = {
+
+ init: function(config) {
+ this.config = config;
+ },
+
+ /**
+ * Method that will be invoked by the mojit controller to obtain data.
+ *
+ * @param callback {function(err,data)} The callback function to call when the
+ * data has been retrieved.
+ */
+ getData: function(callback) {
+ callback(null, { some: 'data' });
+ }
+
+ };
+
+}, '0.0.1', {requires: []});
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/tests/controller.server-tests.js b/dashboard/04_composite_mojits/mojits/FooterMojit/tests/controller.server-tests.js
new file mode 100755
index 0000000..3166df5
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/tests/controller.server-tests.js
@@ -0,0 +1,62 @@
+
+YUI.add('FooterMojit-tests', function(Y) {
+
+ var suite = new YUITest.TestSuite('FooterMojit-tests'),
+ controller = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'FooterMojit user tests',
+
+ setUp: function() {
+ controller = Y.mojito.controllers.FooterMojit;
+ },
+ tearDown: function() {
+ controller = null;
+ },
+
+ 'test mojit': function() {
+ var ac,
+ modelData,
+ assetsResults,
+ doneResults;
+ modelData = { x:'y' };
+ ac = {
+ assets: {
+ addCss: function(css) {
+ assetsResults = css;
+ }
+ },
+ models: {
+ get: function(modelName) {
+ A.areEqual('FooterMojitModelFoo', modelName, 'wrong model name');
+ return {
+ getData: function(cb) {
+ cb(null, modelData);
+ }
+ }
+ }
+ },
+ done: function(data) {
+ doneResults = data;
+ }
+ };
+
+ A.isNotNull(controller);
+ A.isFunction(controller.index);
+ controller.index(ac);
+ A.areSame('./index.css', assetsResults);
+ A.isObject(doneResults);
+ A.areSame('Mojito is working.', doneResults.status);
+ A.isObject(doneResults.data);
+ A.isTrue(doneResults.data.hasOwnProperty('x'));
+ A.areEqual('y', doneResults.data['x']);
+
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'FooterMojit']});
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/tests/models/foo.server-tests.js b/dashboard/04_composite_mojits/mojits/FooterMojit/tests/models/foo.server-tests.js
new file mode 100755
index 0000000..ad1d94b
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/tests/models/foo.server-tests.js
@@ -0,0 +1,43 @@
+
+YUI.add('FooterMojitModelFoo-tests', function(Y, NAME) {
+
+ var suite = new YUITest.TestSuite(NAME),
+ model = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'FooterMojitModelFoo user tests',
+
+ setUp: function() {
+ model = Y.mojito.models.FooterMojitModelFoo;
+ },
+ tearDown: function() {
+ model = null;
+ },
+
+ 'test mojit model': function() {
+ var called = false,
+ cfg = { color: 'red' };
+
+ A.isNotNull(model);
+
+ A.isFunction(model.init);
+ model.init(cfg);
+ A.areSame(cfg, model.config);
+
+ A.isFunction(model.getData);
+ model.getData(function(err, data) {
+ called = true;
+ A.isTrue(!err);
+ A.isObject(data);
+ A.areSame('data', data.some);
+ });
+ A.isTrue(called);
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'FooterMojitModelFoo']});
diff --git a/dashboard/04_composite_mojits/mojits/FooterMojit/views/index.hb.html b/dashboard/04_composite_mojits/mojits/FooterMojit/views/index.hb.html
new file mode 100755
index 0000000..7af3062
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FooterMojit/views/index.hb.html
@@ -0,0 +1,3 @@
+
+ {{title}}
+
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/assets/index.css b/dashboard/04_composite_mojits/mojits/FrameMojit/assets/index.css
new file mode 100755
index 0000000..1cd5114
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/assets/index.css
@@ -0,0 +1,2 @@
+dt { font-weight: bold; }
+.sel { background-color: #FF4; }
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/binders/index.js b/dashboard/04_composite_mojits/mojits/FrameMojit/binders/index.js
new file mode 100755
index 0000000..7da3510
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/binders/index.js
@@ -0,0 +1,59 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('FrameMojitBinderIndex', function(Y, NAME) {
+
+/**
+ * The FrameMojitBinderIndex module.
+ *
+ * @module FrameMojitBinderIndex
+ */
+
+ /**
+ * Constructor for the FrameMojitBinderIndex class.
+ *
+ * @class FrameMojitBinderIndex
+ * @constructor
+ */
+ Y.namespace('mojito.binders')[NAME] = {
+
+ /**
+ * Binder initialization method, invoked after all binders on the page
+ * have been constructed.
+ */
+ init: function(mojitProxy) {
+ this.mojitProxy = mojitProxy;
+ },
+
+ /**
+ * The binder method, invoked to allow the mojit to attach DOM event
+ * handlers.
+ *
+ * @param node {Node} The DOM node to which this mojit is attached.
+ */
+ bind: function(node) {
+ var me = this;
+ this.node = node;
+ /**
+ * Example code for the bind method:
+ *
+ * node.all('dt').on('mouseenter', function(evt) {
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).addClass('sel');
+ *
+ * });
+ * node.all('dt').on('mouseleave', function(evt) {
+ *
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).removeClass('sel');
+ *
+ * });
+ */
+
+ Y.log("bind called");
+ Y.on("domready", function(){
+ Y.one("body").addClass("yui3-skin-sam");
+ });
+ }
+
+ };
+
+}, '0.0.1', {requires: ['event-mouseenter', 'mojito-client']});
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/controller.server.js b/dashboard/04_composite_mojits/mojits/FrameMojit/controller.server.js
new file mode 100755
index 0000000..73f5ee1
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/controller.server.js
@@ -0,0 +1,35 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('FrameMojit', function(Y, NAME) {
+
+/**
+ * The FrameMojit module.
+ *
+ * @module FrameMojit
+ */
+
+ /**
+ * Constructor for the Controller class.
+ *
+ * @class Controller
+ * @constructor
+ */
+ Y.namespace('mojito.controllers')[NAME] = {
+ init: function(config){
+ this.config = config;
+ },
+
+ /**
+ * Method corresponding to the 'index' action.
+ *
+ * @param ac {Object} The ActionContext that provides access
+ * to the Mojito API.
+ */
+ index: function(ac) {
+ ac.composite.done({
+ title: "Trib - Contribute to the Tribe"
+ });
+ }
+
+ };
+
+}, '0.0.1', {requires: ['mojito','mojito-composite-addon']});
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/definition.json b/dashboard/04_composite_mojits/mojits/FrameMojit/definition.json
new file mode 100755
index 0000000..470db80
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/definition.json
@@ -0,0 +1,5 @@
+[
+ {
+ "settings": [ "master" ]
+ }
+]
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/tests/controller.server-tests.js b/dashboard/04_composite_mojits/mojits/FrameMojit/tests/controller.server-tests.js
new file mode 100755
index 0000000..0b3f06a
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/tests/controller.server-tests.js
@@ -0,0 +1,62 @@
+
+YUI.add('FrameMojit-tests', function(Y) {
+
+ var suite = new YUITest.TestSuite('FrameMojit-tests'),
+ controller = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'FrameMojit user tests',
+
+ setUp: function() {
+ controller = Y.mojito.controllers.FrameMojit;
+ },
+ tearDown: function() {
+ controller = null;
+ },
+
+ 'test mojit': function() {
+ var ac,
+ modelData,
+ assetsResults,
+ doneResults;
+ modelData = { x:'y' };
+ ac = {
+ assets: {
+ addCss: function(css) {
+ assetsResults = css;
+ }
+ },
+ models: {
+ get: function(modelName) {
+ A.areEqual('FrameMojitModelFoo', modelName, 'wrong model name');
+ return {
+ getData: function(cb) {
+ cb(null, modelData);
+ }
+ }
+ }
+ },
+ done: function(data) {
+ doneResults = data;
+ }
+ };
+
+ A.isNotNull(controller);
+ A.isFunction(controller.index);
+ controller.index(ac);
+ A.areSame('./index.css', assetsResults);
+ A.isObject(doneResults);
+ A.areSame('Mojito is working.', doneResults.status);
+ A.isObject(doneResults.data);
+ A.isTrue(doneResults.data.hasOwnProperty('x'));
+ A.areEqual('y', doneResults.data['x']);
+
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'FrameMojit']});
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/tests/models/foo.server-tests.js b/dashboard/04_composite_mojits/mojits/FrameMojit/tests/models/foo.server-tests.js
new file mode 100755
index 0000000..cefe908
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/tests/models/foo.server-tests.js
@@ -0,0 +1,43 @@
+
+YUI.add('FrameMojitModelFoo-tests', function(Y, NAME) {
+
+ var suite = new YUITest.TestSuite(NAME),
+ model = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'FrameMojitModelFoo user tests',
+
+ setUp: function() {
+ model = Y.mojito.models.FrameMojitModelFoo;
+ },
+ tearDown: function() {
+ model = null;
+ },
+
+ 'test mojit model': function() {
+ var called = false,
+ cfg = { color: 'red' };
+
+ A.isNotNull(model);
+
+ A.isFunction(model.init);
+ model.init(cfg);
+ A.areSame(cfg, model.config);
+
+ A.isFunction(model.getData);
+ model.getData(function(err, data) {
+ called = true;
+ A.isTrue(!err);
+ A.isObject(data);
+ A.areSame('data', data.some);
+ });
+ A.isTrue(called);
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'FrameMojitModelFoo']});
diff --git a/dashboard/04_composite_mojits/mojits/FrameMojit/views/index.hb.html b/dashboard/04_composite_mojits/mojits/FrameMojit/views/index.hb.html
new file mode 100755
index 0000000..cbb47bb
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/FrameMojit/views/index.hb.html
@@ -0,0 +1,13 @@
+
+
+
{{title}}
+
+
+ {{{body}}}
+
+
+
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/assets/index.css b/dashboard/04_composite_mojits/mojits/HeaderMojit/assets/index.css
new file mode 100755
index 0000000..1cd5114
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/assets/index.css
@@ -0,0 +1,2 @@
+dt { font-weight: bold; }
+.sel { background-color: #FF4; }
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/binders/index.js b/dashboard/04_composite_mojits/mojits/HeaderMojit/binders/index.js
new file mode 100755
index 0000000..6dc8544
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/binders/index.js
@@ -0,0 +1,54 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('HeaderMojitBinderIndex', function(Y, NAME) {
+
+/**
+ * The HeaderMojitBinderIndex module.
+ *
+ * @module HeaderMojitBinderIndex
+ */
+
+ /**
+ * Constructor for the HeaderMojitBinderIndex class.
+ *
+ * @class HeaderMojitBinderIndex
+ * @constructor
+ */
+ Y.namespace('mojito.binders')[NAME] = {
+
+ /**
+ * Binder initialization method, invoked after all binders on the page
+ * have been constructed.
+ */
+ init: function(mojitProxy) {
+ this.mojitProxy = mojitProxy;
+ },
+
+ /**
+ * The binder method, invoked to allow the mojit to attach DOM event
+ * handlers.
+ *
+ * @param node {Node} The DOM node to which this mojit is attached.
+ */
+ bind: function(node) {
+ var me = this;
+ this.node = node;
+ /**
+ * Example code for the bind method:
+ *
+ * node.all('dt').on('mouseenter', function(evt) {
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).addClass('sel');
+ *
+ * });
+ * node.all('dt').on('mouseleave', function(evt) {
+ *
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).removeClass('sel');
+ *
+ * });
+ */
+ }
+
+ };
+
+}, '0.0.1', {requires: ['event-mouseenter', 'mojito-client']});
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/controller.server.js b/dashboard/04_composite_mojits/mojits/HeaderMojit/controller.server.js
new file mode 100755
index 0000000..c91f8f8
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/controller.server.js
@@ -0,0 +1,32 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('HeaderMojit', function(Y, NAME) {
+
+/**
+ * The HeaderMojit module.
+ *
+ * @module HeaderMojit
+ */
+
+ /**
+ * Constructor for the Controller class.
+ *
+ * @class Controller
+ * @constructor
+ */
+ Y.namespace('mojito.controllers')[NAME] = {
+
+ /**
+ * Method corresponding to the 'index' action.
+ *
+ * @param ac {Object} The ActionContext that provides access
+ * to the Mojito API.
+ */
+ index: function(ac) {
+ ac.done({
+ title: ""
+ });
+ }
+
+ };
+
+}, '0.0.1', {requires: ['mojito']});
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/definition.json b/dashboard/04_composite_mojits/mojits/HeaderMojit/definition.json
new file mode 100755
index 0000000..470db80
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/definition.json
@@ -0,0 +1,5 @@
+[
+ {
+ "settings": [ "master" ]
+ }
+]
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/models/foo.server.js b/dashboard/04_composite_mojits/mojits/HeaderMojit/models/foo.server.js
new file mode 100755
index 0000000..59407fe
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/models/foo.server.js
@@ -0,0 +1,34 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('HeaderMojitModelFoo', function(Y, NAME) {
+
+/**
+ * The HeaderMojitModelFoo module.
+ *
+ * @module HeaderMojit
+ */
+
+ /**
+ * Constructor for the HeaderMojitModelFoo class.
+ *
+ * @class HeaderMojitModelFoo
+ * @constructor
+ */
+ Y.namespace('mojito.models')[NAME] = {
+
+ init: function(config) {
+ this.config = config;
+ },
+
+ /**
+ * Method that will be invoked by the mojit controller to obtain data.
+ *
+ * @param callback {function(err,data)} The callback function to call when the
+ * data has been retrieved.
+ */
+ getData: function(callback) {
+ callback(null, { some: 'data' });
+ }
+
+ };
+
+}, '0.0.1', {requires: []});
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/tests/controller.server-tests.js b/dashboard/04_composite_mojits/mojits/HeaderMojit/tests/controller.server-tests.js
new file mode 100755
index 0000000..b304e3e
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/tests/controller.server-tests.js
@@ -0,0 +1,62 @@
+
+YUI.add('HeaderMojit-tests', function(Y) {
+
+ var suite = new YUITest.TestSuite('HeaderMojit-tests'),
+ controller = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'HeaderMojit user tests',
+
+ setUp: function() {
+ controller = Y.mojito.controllers.HeaderMojit;
+ },
+ tearDown: function() {
+ controller = null;
+ },
+
+ 'test mojit': function() {
+ var ac,
+ modelData,
+ assetsResults,
+ doneResults;
+ modelData = { x:'y' };
+ ac = {
+ assets: {
+ addCss: function(css) {
+ assetsResults = css;
+ }
+ },
+ models: {
+ get: function(modelName) {
+ A.areEqual('HeaderMojitModelFoo', modelName, 'wrong model name');
+ return {
+ getData: function(cb) {
+ cb(null, modelData);
+ }
+ }
+ }
+ },
+ done: function(data) {
+ doneResults = data;
+ }
+ };
+
+ A.isNotNull(controller);
+ A.isFunction(controller.index);
+ controller.index(ac);
+ A.areSame('./index.css', assetsResults);
+ A.isObject(doneResults);
+ A.areSame('Mojito is working.', doneResults.status);
+ A.isObject(doneResults.data);
+ A.isTrue(doneResults.data.hasOwnProperty('x'));
+ A.areEqual('y', doneResults.data['x']);
+
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'HeaderMojit']});
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/tests/models/foo.server-tests.js b/dashboard/04_composite_mojits/mojits/HeaderMojit/tests/models/foo.server-tests.js
new file mode 100755
index 0000000..e94c696
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/tests/models/foo.server-tests.js
@@ -0,0 +1,43 @@
+
+YUI.add('HeaderMojitModelFoo-tests', function(Y, NAME) {
+
+ var suite = new YUITest.TestSuite(NAME),
+ model = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'HeaderMojitModelFoo user tests',
+
+ setUp: function() {
+ model = Y.mojito.models.HeaderMojitModelFoo;
+ },
+ tearDown: function() {
+ model = null;
+ },
+
+ 'test mojit model': function() {
+ var called = false,
+ cfg = { color: 'red' };
+
+ A.isNotNull(model);
+
+ A.isFunction(model.init);
+ model.init(cfg);
+ A.areSame(cfg, model.config);
+
+ A.isFunction(model.getData);
+ model.getData(function(err, data) {
+ called = true;
+ A.isTrue(!err);
+ A.isObject(data);
+ A.areSame('data', data.some);
+ });
+ A.isTrue(called);
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'HeaderMojitModelFoo']});
diff --git a/dashboard/04_composite_mojits/mojits/HeaderMojit/views/index.hb.html b/dashboard/04_composite_mojits/mojits/HeaderMojit/views/index.hb.html
new file mode 100755
index 0000000..fd053e1
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/HeaderMojit/views/index.hb.html
@@ -0,0 +1,63 @@
+
+
{{title}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dashboard/04_composite_mojits/mojits/gallery/assets/index.css b/dashboard/04_composite_mojits/mojits/gallery/assets/index.css
new file mode 100755
index 0000000..1cd5114
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/assets/index.css
@@ -0,0 +1,2 @@
+dt { font-weight: bold; }
+.sel { background-color: #FF4; }
diff --git a/dashboard/04_composite_mojits/mojits/gallery/binders/index.js b/dashboard/04_composite_mojits/mojits/gallery/binders/index.js
new file mode 100755
index 0000000..d53a73f
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/binders/index.js
@@ -0,0 +1,54 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('galleryBinderIndex', function(Y, NAME) {
+
+/**
+ * The galleryBinderIndex module.
+ *
+ * @module galleryBinderIndex
+ */
+
+ /**
+ * Constructor for the galleryBinderIndex class.
+ *
+ * @class galleryBinderIndex
+ * @constructor
+ */
+ Y.namespace('mojito.binders')[NAME] = {
+
+ /**
+ * Binder initialization method, invoked after all binders on the page
+ * have been constructed.
+ */
+ init: function(mojitProxy) {
+ this.mojitProxy = mojitProxy;
+ },
+
+ /**
+ * The binder method, invoked to allow the mojit to attach DOM event
+ * handlers.
+ *
+ * @param node {Node} The DOM node to which this mojit is attached.
+ */
+ bind: function(node) {
+ var me = this;
+ this.node = node;
+ /**
+ * Example code for the bind method:
+ *
+ * node.all('dt').on('mouseenter', function(evt) {
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).addClass('sel');
+ *
+ * });
+ * node.all('dt').on('mouseleave', function(evt) {
+ *
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).removeClass('sel');
+ *
+ * });
+ */
+ }
+
+ };
+
+}, '0.0.1', {requires: ['event-mouseenter', 'mojito-client']});
diff --git a/dashboard/04_composite_mojits/mojits/gallery/controller.server.js b/dashboard/04_composite_mojits/mojits/gallery/controller.server.js
new file mode 100755
index 0000000..366b48d
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/controller.server.js
@@ -0,0 +1,40 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('gallery', function(Y, NAME) {
+
+/**
+ * The gallery module.
+ *
+ * @module gallery
+ */
+
+ /**
+ * Constructor for the Controller class.
+ *
+ * @class Controller
+ * @constructor
+ */
+ Y.namespace('mojito.controllers')[NAME] = {
+
+ /**
+ * Method corresponding to the 'index' action.
+ *
+ * @param ac {Object} The ActionContext that provides access
+ * to the Mojito API.
+ */
+ index: function(ac) {
+ ac.models.get('galleryModelFoo').getData(function(err, data) {
+ if (err) {
+ ac.error(err);
+ return;
+ }
+ ac.assets.addCss('./index.css');
+ ac.done({
+ status: 'Mojito is working.',
+ data: data
+ });
+ });
+ }
+
+ };
+
+}, '0.0.1', {requires: ['mojito', 'mojito-assets-addon', 'mojito-models-addon', 'galleryModelFoo']});
diff --git a/dashboard/04_composite_mojits/mojits/gallery/definition.json b/dashboard/04_composite_mojits/mojits/gallery/definition.json
new file mode 100755
index 0000000..470db80
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/definition.json
@@ -0,0 +1,5 @@
+[
+ {
+ "settings": [ "master" ]
+ }
+]
diff --git a/dashboard/04_composite_mojits/mojits/gallery/models/foo.server.js b/dashboard/04_composite_mojits/mojits/gallery/models/foo.server.js
new file mode 100755
index 0000000..ab3b79c
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/models/foo.server.js
@@ -0,0 +1,34 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('galleryModelFoo', function(Y, NAME) {
+
+/**
+ * The galleryModelFoo module.
+ *
+ * @module gallery
+ */
+
+ /**
+ * Constructor for the galleryModelFoo class.
+ *
+ * @class galleryModelFoo
+ * @constructor
+ */
+ Y.namespace('mojito.models')[NAME] = {
+
+ init: function(config) {
+ this.config = config;
+ },
+
+ /**
+ * Method that will be invoked by the mojit controller to obtain data.
+ *
+ * @param callback {function(err,data)} The callback function to call when the
+ * data has been retrieved.
+ */
+ getData: function(callback) {
+ callback(null, { some: 'data' });
+ }
+
+ };
+
+}, '0.0.1', {requires: []});
diff --git a/dashboard/04_composite_mojits/mojits/gallery/tests/controller.server-tests.js b/dashboard/04_composite_mojits/mojits/gallery/tests/controller.server-tests.js
new file mode 100755
index 0000000..bc2b7cc
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/tests/controller.server-tests.js
@@ -0,0 +1,62 @@
+
+YUI.add('gallery-tests', function(Y) {
+
+ var suite = new YUITest.TestSuite('gallery-tests'),
+ controller = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'gallery user tests',
+
+ setUp: function() {
+ controller = Y.mojito.controllers.gallery;
+ },
+ tearDown: function() {
+ controller = null;
+ },
+
+ 'test mojit': function() {
+ var ac,
+ modelData,
+ assetsResults,
+ doneResults;
+ modelData = { x:'y' };
+ ac = {
+ assets: {
+ addCss: function(css) {
+ assetsResults = css;
+ }
+ },
+ models: {
+ get: function(modelName) {
+ A.areEqual('galleryModelFoo', modelName, 'wrong model name');
+ return {
+ getData: function(cb) {
+ cb(null, modelData);
+ }
+ }
+ }
+ },
+ done: function(data) {
+ doneResults = data;
+ }
+ };
+
+ A.isNotNull(controller);
+ A.isFunction(controller.index);
+ controller.index(ac);
+ A.areSame('./index.css', assetsResults);
+ A.isObject(doneResults);
+ A.areSame('Mojito is working.', doneResults.status);
+ A.isObject(doneResults.data);
+ A.isTrue(doneResults.data.hasOwnProperty('x'));
+ A.areEqual('y', doneResults.data['x']);
+
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'gallery']});
diff --git a/dashboard/04_composite_mojits/mojits/gallery/tests/models/foo.server-tests.js b/dashboard/04_composite_mojits/mojits/gallery/tests/models/foo.server-tests.js
new file mode 100755
index 0000000..b0be472
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/tests/models/foo.server-tests.js
@@ -0,0 +1,43 @@
+
+YUI.add('galleryModelFoo-tests', function(Y, NAME) {
+
+ var suite = new YUITest.TestSuite(NAME),
+ model = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'galleryModelFoo user tests',
+
+ setUp: function() {
+ model = Y.mojito.models.galleryModelFoo;
+ },
+ tearDown: function() {
+ model = null;
+ },
+
+ 'test mojit model': function() {
+ var called = false,
+ cfg = { color: 'red' };
+
+ A.isNotNull(model);
+
+ A.isFunction(model.init);
+ model.init(cfg);
+ A.areSame(cfg, model.config);
+
+ A.isFunction(model.getData);
+ model.getData(function(err, data) {
+ called = true;
+ A.isTrue(!err);
+ A.isObject(data);
+ A.areSame('data', data.some);
+ });
+ A.isTrue(called);
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'galleryModelFoo']});
diff --git a/dashboard/04_composite_mojits/mojits/gallery/views/index.hb.html b/dashboard/04_composite_mojits/mojits/gallery/views/index.hb.html
new file mode 100755
index 0000000..53d6e9f
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/gallery/views/index.hb.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Number of Modules in the Gallery:
+
+
+
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/assets/index.css b/dashboard/04_composite_mojits/mojits/githubMojit/assets/index.css
new file mode 100755
index 0000000..1cd5114
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/assets/index.css
@@ -0,0 +1,2 @@
+dt { font-weight: bold; }
+.sel { background-color: #FF4; }
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/binders/index.js b/dashboard/04_composite_mojits/mojits/githubMojit/binders/index.js
new file mode 100755
index 0000000..ceb5c99
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/binders/index.js
@@ -0,0 +1,54 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('githubMojitBinderIndex', function(Y, NAME) {
+
+/**
+ * The githubMojitBinderIndex module.
+ *
+ * @module githubMojitBinderIndex
+ */
+
+ /**
+ * Constructor for the githubMojitBinderIndex class.
+ *
+ * @class githubMojitBinderIndex
+ * @constructor
+ */
+ Y.namespace('mojito.binders')[NAME] = {
+
+ /**
+ * Binder initialization method, invoked after all binders on the page
+ * have been constructed.
+ */
+ init: function(mojitProxy) {
+ this.mojitProxy = mojitProxy;
+ },
+
+ /**
+ * The binder method, invoked to allow the mojit to attach DOM event
+ * handlers.
+ *
+ * @param node {Node} The DOM node to which this mojit is attached.
+ */
+ bind: function(node) {
+ var me = this;
+ this.node = node;
+ /**
+ * Example code for the bind method:
+ *
+ * node.all('dt').on('mouseenter', function(evt) {
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).addClass('sel');
+ *
+ * });
+ * node.all('dt').on('mouseleave', function(evt) {
+ *
+ * var dd = '#dd_' + evt.target.get('text');
+ * me.node.one(dd).removeClass('sel');
+ *
+ * });
+ */
+ }
+
+ };
+
+}, '0.0.1', {requires: ['event-mouseenter', 'mojito-client']});
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/controller.server.js b/dashboard/04_composite_mojits/mojits/githubMojit/controller.server.js
new file mode 100755
index 0000000..20cf4e0
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/controller.server.js
@@ -0,0 +1,42 @@
+/*jslint anon:true, sloppy:true, nomen:true*/
+YUI.add('githubMojit', function(Y, NAME) {
+
+/**
+ * The githubMojit module.
+ *
+ * @module githubMojit
+ */
+
+ /**
+ * Constructor for the Controller class.
+ *
+ * @class Controller
+ * @constructor
+ */
+ Y.namespace('mojito.controllers')[NAME] = {
+
+ /**
+ * Method corresponding to the 'index' action.
+ *
+ * @param ac {Object} The ActionContext that provides access
+ * to the Mojito API.
+ */
+ index: function(ac) {
+
+ var model = ac.models.get('StatsModelYQL');
+ Y.log(model);
+ model.getData({}, function(data){
+ Y.log("githubmojit -index - model.getData:");
+ Y.log(data);
+
+ ac.done({
+ title: "",
+ watchers: data.watchers,
+ forks: data.forks
+ });
+ });
+ }
+
+ };
+
+}, '0.0.1', {requires: ['mojito', 'mojito-models-addon']});
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/definition.json b/dashboard/04_composite_mojits/mojits/githubMojit/definition.json
new file mode 100755
index 0000000..470db80
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/definition.json
@@ -0,0 +1,5 @@
+[
+ {
+ "settings": [ "master" ]
+ }
+]
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/models/yql.server.js b/dashboard/04_composite_mojits/mojits/githubMojit/models/yql.server.js
new file mode 100755
index 0000000..6e4dbb6
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/models/yql.server.js
@@ -0,0 +1,45 @@
+YUI.add('StatsModelYQL', function(Y, NAME) {
+
+
+ Y.mojito.models[NAME] = {
+
+ init: function(config) {
+ this.config = config;
+ },
+
+ getData: function(params, callback) {
+ var //yqlTable = 'store://kIfKmDunyT35ymUmFHJw0M',
+ yqlTable = 'https://raw.github.com/triptych/trib/master/src/yql/github.xml',
+ query = "use '{table}' as yahoo.awooldri.github.repo; select watchers,forks from yahoo.awooldri.github.repo where id='yql' and repo='yql-tables'",
+ queryParams = {
+ table: yqlTable
+ },
+ cookedQuery = Y.substitute(query, queryParams);
+ Y.log("getData called");
+ Y.log("cookedQuery:" + cookedQuery);
+ Y.YQL(cookedQuery, Y.bind(this.onDataReturn, this, callback));
+ },
+
+ onDataReturn: function (cb, result) {
+ Y.log("onDataReturn called");
+ if (typeof result.error === 'undefined') {
+
+ Y.log("result:");
+ Y.log(result);
+
+
+
+ var results = result.query.results.json;
+ Y.log("results.json:");
+ Y.log(results);
+
+
+ cb(results);
+ } else {
+ cb(result.error);
+ }
+ }
+
+ };
+
+}, '0.0.1', {requires: ['yql', 'substitute']});
\ No newline at end of file
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/tests/controller.server-tests.js b/dashboard/04_composite_mojits/mojits/githubMojit/tests/controller.server-tests.js
new file mode 100755
index 0000000..a1f53be
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/tests/controller.server-tests.js
@@ -0,0 +1,62 @@
+
+YUI.add('githubMojit-tests', function(Y) {
+
+ var suite = new YUITest.TestSuite('githubMojit-tests'),
+ controller = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'githubMojit user tests',
+
+ setUp: function() {
+ controller = Y.mojito.controllers.githubMojit;
+ },
+ tearDown: function() {
+ controller = null;
+ },
+
+ 'test mojit': function() {
+ var ac,
+ modelData,
+ assetsResults,
+ doneResults;
+ modelData = { x:'y' };
+ ac = {
+ assets: {
+ addCss: function(css) {
+ assetsResults = css;
+ }
+ },
+ models: {
+ get: function(modelName) {
+ A.areEqual('githubMojitModelFoo', modelName, 'wrong model name');
+ return {
+ getData: function(cb) {
+ cb(null, modelData);
+ }
+ }
+ }
+ },
+ done: function(data) {
+ doneResults = data;
+ }
+ };
+
+ A.isNotNull(controller);
+ A.isFunction(controller.index);
+ controller.index(ac);
+ A.areSame('./index.css', assetsResults);
+ A.isObject(doneResults);
+ A.areSame('Mojito is working.', doneResults.status);
+ A.isObject(doneResults.data);
+ A.isTrue(doneResults.data.hasOwnProperty('x'));
+ A.areEqual('y', doneResults.data['x']);
+
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'githubMojit']});
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/tests/models/foo.server-tests.js b/dashboard/04_composite_mojits/mojits/githubMojit/tests/models/foo.server-tests.js
new file mode 100755
index 0000000..c43ff45
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/tests/models/foo.server-tests.js
@@ -0,0 +1,43 @@
+
+YUI.add('githubMojitModelFoo-tests', function(Y, NAME) {
+
+ var suite = new YUITest.TestSuite(NAME),
+ model = null,
+ A = YUITest.Assert;
+
+ suite.add(new YUITest.TestCase({
+
+ name: 'githubMojitModelFoo user tests',
+
+ setUp: function() {
+ model = Y.mojito.models.githubMojitModelFoo;
+ },
+ tearDown: function() {
+ model = null;
+ },
+
+ 'test mojit model': function() {
+ var called = false,
+ cfg = { color: 'red' };
+
+ A.isNotNull(model);
+
+ A.isFunction(model.init);
+ model.init(cfg);
+ A.areSame(cfg, model.config);
+
+ A.isFunction(model.getData);
+ model.getData(function(err, data) {
+ called = true;
+ A.isTrue(!err);
+ A.isObject(data);
+ A.areSame('data', data.some);
+ });
+ A.isTrue(called);
+ }
+
+ }));
+
+ YUITest.TestRunner.add(suite);
+
+}, '0.0.1', {requires: ['mojito-test', 'githubMojitModelFoo']});
diff --git a/dashboard/04_composite_mojits/mojits/githubMojit/views/index.hb.html b/dashboard/04_composite_mojits/mojits/githubMojit/views/index.hb.html
new file mode 100755
index 0000000..d0927e9
--- /dev/null
+++ b/dashboard/04_composite_mojits/mojits/githubMojit/views/index.hb.html
@@ -0,0 +1,8 @@
+
+
{{title}}
+
+
YUI GitHub Stats
+
Github watchers: {{watchers}}
+
Github forks: {{forks}}
+
+
diff --git a/dashboard/04_composite_mojits/package.json b/dashboard/04_composite_mojits/package.json
new file mode 100644
index 0000000..a274428
--- /dev/null
+++ b/dashboard/04_composite_mojits/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "04_Composite_mojits",
+ "description": "My Mojito application",
+ "version": "0.0.1",
+ "author": {
+ "name": "Your Name",
+ "email": "nobody@yahoo-inc.com"
+ },
+ "contributors": [
+ {
+ "name": "Your Name",
+ "email": "nobody@yahoo-inc.com"
+ }
+ ],
+ "dependencies": {
+ "mojito": "0.5.x"
+ },
+ "engines": {
+ "node": ">0.6"
+ }
+}
diff --git a/dashboard/04_composite_mojits/routes.json b/dashboard/04_composite_mojits/routes.json
new file mode 100644
index 0000000..15d7134
--- /dev/null
+++ b/dashboard/04_composite_mojits/routes.json
@@ -0,0 +1,25 @@
+[{
+ "settings": [ "master" ],
+ "root": {
+ "verbs": ["get"],
+ "path": "/",
+ "call": "tribframe.index"
+ },
+ "header": {
+ "verbs":["get"],
+ "path": "/header",
+ "call": "header.index"
+ },
+ "body": {
+ "verbs": ["get"],
+ "path": "/body",
+ "call": "body.index"
+ },
+ "footer": {
+ "verbs": ["get"],
+ "path": "/footer",
+ "call": "footer.index"
+ }
+
+
+}]
diff --git a/dashboard/04_composite_mojits/server.js b/dashboard/04_composite_mojits/server.js
new file mode 100644
index 0000000..7672446
--- /dev/null
+++ b/dashboard/04_composite_mojits/server.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011-2013, Yahoo! Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
+
+
+/*jslint anon:true, sloppy:true, nomen:true*/
+
+process.chdir(__dirname);
+
+/*
+ * Create the MojitoServer instance we'll interact with. Options can be passed
+ * using an object with the desired key/value pairs.
+ */
+var Mojito = require('mojito');
+var app = Mojito.createServer();
+
+// ---------------------------------------------------------------------------
+// Different hosting environments require different approaches to starting the
+// server. Adjust below to match the requirements of your hosting environment.
+// ---------------------------------------------------------------------------
+
+module.exports = app.listen();