Skip to content
This repository has been archived by the owner on Jun 9, 2022. It is now read-only.

Commit

Permalink
Merge adf5c1d into 446522b
Browse files Browse the repository at this point in the history
  • Loading branch information
georgecrawford committed Dec 20, 2013
2 parents 446522b + adf5c1d commit 8a5f9ec
Show file tree
Hide file tree
Showing 19 changed files with 1,054 additions and 919 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -98,4 +98,4 @@ Licensed under the MIT license.

## Credits and collaboration

The lead developer of FruitMachine is [Wilson Page](http://github.com/wilsonpage) at FT Labs. All open source code released by FT Labs is licenced under the MIT licence. We welcome comments, feedback and suggestions. Please feel free to raise an issue or pull request. Enjoy...
The lead developer of FruitMachine is [Wilson Page](http://github.com/wilsonpage) at FT Labs. All open source code released by FT Labs is licenced under the MIT licence. We welcome comments, feedback and suggestions. Please feel free to raise an issue or pull request. Enjoy...
190 changes: 105 additions & 85 deletions build/fruitmachine.js
Expand Up @@ -140,75 +140,7 @@ module.exports = function(options) {
return events(fm);
};

},{"./define":4,"./module":5,"utils":6,"event":7}],6:[function(require,module,exports){

/*jshint browser:true, node:true*/

'use strict';

exports.bind = function(method, context) {
return function() { return method.apply(context, arguments); };
};

exports.isArray = function(arg) {
return arg instanceof Array;
},

exports.mixin = function(original, source) {
for (var key in source) original[key] = source[key];
return original;
},

exports.byId = function(id, el) {
if (el) return el.querySelector('#' + id);
},

/**
* Inserts an item into an array.
* Has the option to state an index.
*
* @param {*} item
* @param {Array} array
* @param {Number} index
* @return void
*/
exports.insert = function(item, array, index) {
if (typeof index !== 'undefined') {
array.splice(index, 0, item);
} else {
array.push(item);
}
},

exports.toNode = function(html) {
var el = document.createElement('div');
el.innerHTML = html;
return el.removeChild(el.firstElementChild);
},

// Determine if we have a DOM
// in the current environment.
exports.hasDom = function() {
return typeof document !== 'undefined';
};

var i = 0;
exports.uniqueId = function(prefix) {
return (prefix || 'id') + ((++i) * Math.round(Math.random() * 100000));
};

exports.keys = function(object) {
var keys = [];
for (var key in object) keys.push(key);
return keys;
};

exports.isPlainObject = function(ob) {
if (!ob) return false;
var c = (ob.constructor || '').toString();
return !!~c.indexOf('Object');
};
},{}],7:[function(require,module,exports){
},{"./define":4,"./module":5,"utils":6,"event":7}],7:[function(require,module,exports){

/**
* Event
Expand Down Expand Up @@ -322,6 +254,74 @@ function mixin(a, b) {
for (var key in b) a[key] = b[key];
return a;
}
},{}],6:[function(require,module,exports){

/*jshint browser:true, node:true*/

'use strict';

exports.bind = function(method, context) {
return function() { return method.apply(context, arguments); };
};

exports.isArray = function(arg) {
return arg instanceof Array;
},

exports.mixin = function(original, source) {
for (var key in source) original[key] = source[key];
return original;
},

exports.byId = function(id, el) {
if (el) return el.querySelector('#' + id);
},

/**
* Inserts an item into an array.
* Has the option to state an index.
*
* @param {*} item
* @param {Array} array
* @param {Number} index
* @return void
*/
exports.insert = function(item, array, index) {
if (typeof index !== 'undefined') {
array.splice(index, 0, item);
} else {
array.push(item);
}
},

exports.toNode = function(html) {
var el = document.createElement('div');
el.innerHTML = html;
return el.removeChild(el.firstElementChild);
},

// Determine if we have a DOM
// in the current environment.
exports.hasDom = function() {
return typeof document !== 'undefined';
};

var i = 0;
exports.uniqueId = function(prefix) {
return (prefix || 'id') + ((++i) * Math.round(Math.random() * 100000));
};

exports.keys = function(object) {
var keys = [];
for (var key in object) keys.push(key);
return keys;
};

exports.isPlainObject = function(ob) {
if (!ob) return false;
var c = (ob.constructor || '').toString();
return !!~c.indexOf('Object');
};
},{}],8:[function(require,module,exports){

'use strict';
Expand Down Expand Up @@ -547,8 +547,8 @@ module.exports = function(fm) {
this._id = options.id || util.uniqueId();
this._fmid = options.fmid || util.uniqueId('fmid');
this.tag = options.tag || this.tag || 'div';
this.classes = this.classes || options.classes || [];
this.helpers = this.helpers || options.helpers || [];
this.classes = options.classes || this.classes || [];
this.helpers = options.helpers || this.helpers || [];
this.template = this._setTemplate(options.template || this.template);
this.slot = options.slot;

Expand Down Expand Up @@ -1303,36 +1303,56 @@ module.exports = function(fm) {
};

/**
* Returns a JSON represention of
* @deprecated
*/
proto.toJSON = function(options) {
return this.serialize(options);
};

/**
* Returns a serialized represention of
* a FruitMachine Module. This can
* be generated serverside and
* passed into new FruitMachine(json)
* passed into new FruitMachine(serialized)
* to inflate serverside rendered
* views.
*
* Options:
*
* - `inflatable` Whether the returned object should retain references to DOM ids for use with client-side inflation of views
*
* @param {Object} options
* @return {Object}
* @api public
*/
proto.toJSON = function() {
var json = {};
json.children = [];
proto.serialize = function(options) {
var serialized = {};

// Shallow clone the options
options = mixin({
inflatable: true
}, options);

serialized.children = [];

// Recurse
this.each(function(child) {
json.children.push(child.toJSON());
serialized.children.push(child.serialize());
});

json.id = this.id();
json.fmid = this._fmid;
json.module = this.module();
json.model = this.model.toJSON();
json.slot = this.slot;
serialized.id = this.id();
serialized.module = this.module();
serialized.model = this.model.toJSON();
serialized.slot = this.slot;

if (options.inflatable) serialized.fmid = this._fmid;

// Fire a hook to allow third
// parties to alter the json output
this.fireStatic('tojson', json);
// parties to alter the output
this.fireStatic('tojson', serialized); // @deprecated
this.fireStatic('serialize', serialized);

return json;
return serialized;
};

// Events
Expand Down
2 changes: 1 addition & 1 deletion build/fruitmachine.min.js

Large diffs are not rendered by default.

37 changes: 20 additions & 17 deletions docs/api.md
Expand Up @@ -3,7 +3,7 @@
### fruitmachine.define()

Defines a module.
\nOptions:
Options:

- `name {String}` the name of the module
- `tag {String}` the tagName to use for the root element
Expand All @@ -18,7 +18,7 @@ Defines a module.
### Module#Module

Module constructor
\nOptions:
Options:

- `id {String}` a unique id to query by
- `model {Object|Model}` the data with which to associate this module
Expand All @@ -31,7 +31,7 @@ Module constructor
### Module#add()

Adds a child view(s) to another Module.
\nOptions:
Options:

- `at` The child index at which to insert
- `inject` Injects the child's view element into the parent's
Expand All @@ -43,7 +43,7 @@ Removes a child view from
its current Module contexts
and also from the DOM unless
otherwise stated.
\nOptions:
Options:

- `fromDOM` Whether the element should be removed from the DOM (default `true`)

Expand All @@ -65,7 +65,7 @@ otherwise stated.
Returns a decendent module
by id, or if called with no
arguments, returns this view's id.
\n*Example:*
*Example:*

myModule.id();
//=> 'my_view_id'
Expand All @@ -79,7 +79,7 @@ Returns the first descendent
Module with the passed module type.
If called with no arguments the
Module's own module type is returned.
\n*Example:*
*Example:*

// Assuming 'myModule' has 3 descendent
// views with the module type 'apple'
Expand All @@ -93,7 +93,7 @@ Returns a list of descendent
Modules that match the module
type given (Similar to
Element.querySelectorAll();).
\n*Example:*
*Example:*

// Assuming 'myModule' has 3 descendent
// views with the module type 'apple'
Expand All @@ -106,7 +106,7 @@ Element.querySelectorAll();).
Calls the passed function
for each of the view's
children.
\n*Example:*
*Example:*

myModule.each(function(child) {
// Do stuff with each child view...
Expand All @@ -119,7 +119,7 @@ any descendent views returning
an html string. All data in the
views model is made accessible
to the template.
\nChild views are printed into the
Child views are printed into the
parent template by `id`. Alternatively
children can be iterated over a a list
and printed with `{{{child}}}}`.
Expand All @@ -140,13 +140,13 @@ and printed with `{{{child}}}}`.
Renders the view and replaces
the `view.el` with a freshly
rendered node.
\nFires a `render` event on the view.
Fires a `render` event on the view.

### Module#setup()

Sets up a view and all descendent
views.
\nSetup will be aborted if no `view.el`
Setup will be aborted if no `view.el`
is found. If a view is already setup,
teardown is run first to prevent a
view being setup twice.
Expand All @@ -161,7 +161,7 @@ Options:

Tearsdown a view and all descendent
views that have been setup.
\nYour custom `teardown` method is
Your custom `teardown` method is
called and a `teardown` event is fired.

Options:
Expand All @@ -174,7 +174,7 @@ Completely destroys a view. This means
a view is torn down, removed from it's
current layout context and removed
from the DOM.
\nYour custom `destroy` method is
Your custom `destroy` method is
called and a `destroy` event is fired.

NOTE: `.remove()` is only run on the view
Expand All @@ -187,7 +187,7 @@ Options:
### Module#empty()

Destroys all children.
\nIs this needed?
Is this needed?

### Module#inject()

Expand All @@ -199,14 +199,17 @@ and appends the view into it.
Appends the view element into
the destination element.

### Module#toJSON()
### Module#serialize()

Returns a JSON represention of
Returns a serialized represention of
a FruitMachine Module. This can
be generated serverside and
passed into new FruitMachine(json)
passed into new FruitMachine(serialized)
to inflate serverside rendered
views.
Options:

- `inflatable` Whether the returned object should retain references to DOM ids for use with client-side inflation of views

### Module#on()

Expand Down
5 changes: 2 additions & 3 deletions docs/server-side-rendering.md
Expand Up @@ -25,9 +25,8 @@ var Apple = require('./apple');
app.get('/', function(req, res) {
var apple = new Apple();
var html = apple.toHTML();
var json = apple.toJSON();

json = JSON.stringify(json);
var serialized = apple.serialize();
var json = JSON.stringify(serialized);

// Imagine this response is also
// wrapped in usual document boilerplate
Expand Down

0 comments on commit 8a5f9ec

Please sign in to comment.