Skip to content

Commit

Permalink
Upgrade htmlbars to 0.11.1, re-wrote each helper and added basic test…
Browse files Browse the repository at this point in the history
…s for it.
  • Loading branch information
amiller-gh committed Mar 13, 2015
1 parent 643858e commit a8746dd
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 88 deletions.
3 changes: 2 additions & 1 deletion Gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ gulp.task('runtime', ['amd'], function() {
'wrap/start.frag',
'bower_components/almond/almond.js',
'node_modules/htmlbars/dist/amd/htmlbars-util.amd.js',
'node_modules/htmlbars/dist/amd/morph.amd.js',
'node_modules/htmlbars/dist/amd/morph-attr.amd.js',
'node_modules/htmlbars/dist/amd/dom-helper.amd.js',
'dist/rebound.runtime.js',
'wrap/end.runtime.frag'
])
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reboundjs",
"version": "0.0.57",
"version": "0.0.58",
"description": "Automatic data binding for Backbone using HTMLBars.",
"main": "dist/cjs/rebound-precompiler/rebound-precompiler.js",
"scripts": {
Expand All @@ -22,7 +22,7 @@
"package.json"
],
"dependencies": {
"htmlbars": "^0.8.3"
"htmlbars": "^0.11.1"
},
"devDependencies": {
"bower": "~1.3.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/rebound-compiler/lib/rebound-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { compile as htmlbarsCompile, compileSpec as htmlbarsCompileSpec } from "htmlbars-compiler/compiler";
import { merge } from "htmlbars-util/object-utils";
import DOMHelper from "morph/dom-helper";
import DOMHelper from "dom-helper";
import helpers from "rebound-component/helpers";
import hooks from "rebound-component/hooks";

Expand Down
2 changes: 1 addition & 1 deletion packages/rebound-component/lib/component.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Rebound Component
// ----------------

import DOMHelper from "morph/dom-helper";
import DOMHelper from "dom-helper";
import hooks from "rebound-component/hooks";
import helpers from "rebound-component/helpers";
import $ from "rebound-component/utils";
Expand Down
71 changes: 25 additions & 46 deletions packages/rebound-component/lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,64 +201,43 @@ helpers.each = function(params, hash, options, env){
if(_.isNull(params[0]) || _.isUndefined(params[0])){ console.warn('Undefined value passed to each helper! Maybe try providing a default value?', options.context); return null; }

var value = (params[0].isCollection) ? params[0].models : params[0], // Accepts collections or arrays
start, end, // used below to remove trailing junk morphs from the dom
morph = options.placeholder.firstChildMorph, obj, next, lazyValue, nmorph, i, // used below to remove trailing junk morphs from the dom
position, // Stores the iterated element's integer position in the dom list
currentModel = function(element, index, array, cid){
return element.cid === cid; // Returns true if currently observed element is the current model.
};

// Create our morph array if it doesnt exist
options.placeholder.morphs = options.placeholder.morphs || [];
// For each item in this collection
for(i=0;i < value.length;i++){
obj = value[i];
next = (morph) ? morph.nextMorph : null;

_.each(value, function(obj, key, list){
// If this morph is the rendered version of this model, continue to the next one.
if(morph && morph.cid == obj.cid){ morph = next; continue; }

if(!_.isFunction(obj.set)){ return console.error('Model ', obj, 'has no method .set()!'); }
// Create a lazyvalue whos value is the content inside our block helper rendered in the context of this current list object. Returns the rendered dom for this list item.
lazyValue = new LazyValue(function(){
return options.template.render(obj, options, options.placeholder.contextualElement, [obj]);
}, {morph: options.placeholder});

position = findIndex(options.placeholder.morphs, currentModel, obj.cid);
// Insert our newly rendered value (a document tree) into our placeholder (the containing element) at its requested position (where we currently are in the object list)
nmorph = options.placeholder.insertContentBeforeMorph(lazyValue.value(), morph);

// TODO: These need to be re-added in as data attributes
// Even if rendered already, update each element's index, key, first and last in case of order changes or element removals
// if(_.isArray(value)){
// obj.set({'@index': key, '@first': (key === 0), '@last': (key === value.length-1)}, {silent: true});
// }
//
// if(!_.isArray(value) && _.isObject(value)){
// obj.set({'@key' : key}, {silent: true});
// }
// Label the inserted morph element with this model's cid
nmorph.cid = obj.cid;

// If this model is not the morph element at this index
if(position !== key){
// Destroy the old morph that was here
morph && morph.destroy();

// Create a lazyvalue whos value is the content inside our block helper rendered in the context of this current list object. Returns the rendered dom for this list element.
var lazyValue = new LazyValue(function(){
return options.template.render(((options.template.blockParams === 0)?obj:options.context), options, (options.morph.contextualElement || options.morph.element), [obj]);
}, {morph: options.placeholder});

// If this model is rendered somewhere else in the list, destroy it
if(position > -1){
options.placeholder.morphs[position].destroy();
}

// Destroy the morph we're replacing
if(options.placeholder.morphs[key]){
options.placeholder.morphs[key].destroy();
}

// Insert our newly rendered value (a document tree) into our placeholder (the containing element) at its requested position (where we currently are in the object list)
options.placeholder.insert(key, lazyValue.value());

// Label the inserted morph element with this model's cid
options.placeholder.morphs[key].cid = obj.cid;

}

}, this);
// Move on to the next morph
morph = next;
}

// If any more morphs are left over, remove them. We've already gone through all the models.
start = value.length;
end = options.placeholder.morphs.length - 1;
for(end; start <= end; end--){
options.placeholder.morphs[end].destroy();
// // If any more morphs are left over, remove them. We've already gone through all the models.
while(morph){
next = morph.nextMorph;
morph.destroy();
morph = next;
}

// Return null prevent's re-rending of our placeholder. Our placeholder (containing element) now has all the dom we need.
Expand Down
8 changes: 4 additions & 4 deletions packages/rebound-component/lib/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ hooks.block = function block(env, morph, context, path, params, hash, template,

value = lazyValue.value();
value = (_.isUndefined(value)) ? '' : value;
if(!_.isNull(value)){ morph.append(value); }
if(!_.isNull(value)){ morph.appendContent(value); }

// Observe this content morph's parent's children.
// When the morph element's containing element (morph) is removed, clean up the lazyvalue.
Expand Down Expand Up @@ -272,7 +272,7 @@ hooks.inline = function inline(env, morph, context, path, params, hash) {

value = lazyValue.value();
value = (_.isUndefined(value)) ? '' : value;
if(!_.isNull(value)){ morph.append(value); }
if(!_.isNull(value)){ morph.appendContent(value); }

// Observe this content morph's parent's children.
// When the morph element's containing element (morph) is removed, clean up the lazyvalue.
Expand Down Expand Up @@ -311,7 +311,7 @@ hooks.content = function content(env, morph, context, path) {

value = lazyValue.value();
value = (_.isUndefined(value)) ? '' : value;
if(!_.isNull(value)){ morph.append(value); }
if(!_.isNull(value)){ morph.appendContent(value); }

// Observe this content morph's parent's children.
// When the morph element's containing element (morph) is removed, clean up the lazyvalue.
Expand Down Expand Up @@ -555,7 +555,7 @@ hooks.component = function(env, morph, context, tagName, contextData, template)
});

value = lazyValue.value();
if(value !== undefined){ morph.append(value); }
if(value !== undefined){ morph.appendContent(value); }
}
};

Expand Down
4 changes: 2 additions & 2 deletions packages/rebound-component/lib/lazy-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ LazyValue.prototype = {
},

notify: function(sender) {
// TODO: This check won't be necessary once removed DOM has been cleaned of any bindings.
// TODO: This check won't be necessary once removed DOM has been cleaned of any bindings.
// If this lazyValue's morph does not have an immediate parentNode, it has been removed from the dom tree. Destroy it.
// Right now, DOM that contains morphs throw an error if it is removed by another lazyvalue before those morphs re-evaluate.
if(this.morph && this.morph.start && !this.morph.start.parentNode) return this.destroy();
if(this.morph && this.morph.firstNode && !this.morph.firstNode.parentNode) return this.destroy();
var cache = this.cache,
parent,
subscribers;
Expand Down
Loading

0 comments on commit a8746dd

Please sign in to comment.