Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Assetfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Encoding.default_external = "UTF-8" if defined?(Encoding)

require "rake-pipeline-web-filters"
require "json"
require "uglifier"
Expand Down
380 changes: 226 additions & 154 deletions lib/handlebars-1.0.rc.1.js → lib/handlebars-1.0.rc.2.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/ember-handlebars-compiler/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var objectCreate = Object.create || function(parent) {
};

var Handlebars = this.Handlebars || Ember.imports.Handlebars;
Ember.assert("Ember Handlebars requires Handlebars 1.0.beta.5 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.beta\.[56789]$|^1\.0\.rc\.[123456789]+/));
Ember.assert("Ember Handlebars requires Handlebars 1.0.rc.2 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.rc\.[23456789]+/));

/**
Prepares the Handlebars templating library for use inside Ember's view
Expand Down
55 changes: 40 additions & 15 deletions packages/ember-handlebars/lib/ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ var normalizePath = Ember.Handlebars.normalizePath = function(root, path, data)
@param {String} path The path to be lookedup
@param {Object} options The template's option hash
*/
Ember.Handlebars.get = function(root, path, options) {
var handlebarsGet = Ember.Handlebars.get = function(root, path, options) {
var data = options && options.data,
normalizedPath = normalizePath(root, path, data),
value;
Expand All @@ -76,6 +76,41 @@ Ember.Handlebars.get = function(root, path, options) {
};
Ember.Handlebars.getPath = Ember.deprecateFunc('`Ember.Handlebars.getPath` has been changed to `Ember.Handlebars.get` for consistency.', Ember.Handlebars.get);

Ember.Handlebars.resolveParams = function(context, params, options) {
var resolvedParams = [], types = options.types, param, type;

for (var i=0, l=params.length; i<l; i++) {
param = params[i];
type = types[i];

if (type === 'ID') {
resolvedParams.push(handlebarsGet(context, param, options));
} else {
resolvedParams.push(param);
}
}

return resolvedParams;
};

Ember.Handlebars.resolveHash = function(context, hash, options) {
var resolvedHash = {}, types = options.hashTypes, type;

for (var key in hash) {
if (!hash.hasOwnProperty(key)) { continue; }

type = types[key];

if (type === 'ID') {
resolvedHash[key] = handlebarsGet(context, hash[key], options);
} else {
resolvedHash[key] = hash[key];
}
}

return resolvedHash;
};

/**
@private

Expand Down Expand Up @@ -192,21 +227,11 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
Ember.run.scheduleOnce('render', bindView, 'rerender');
};

Ember.addObserver(pathRoot, path, observer);
loc = 0;
while(loc < dependentKeys.length) {
Ember.addObserver(pathRoot, path + '.' + dependentKeys[loc], observer);
loc += 1;
}
view.registerObserver(pathRoot, path, observer);

view.one('willClearRender', function() {
Ember.removeObserver(pathRoot, path, observer);
loc = 0;
while(loc < dependentKeys.length) {
Ember.removeObserver(pathRoot, path + '.' + dependentKeys[loc], observer);
loc += 1;
}
});
for (var i=0, l=dependentKeys.length; i<l; i++) {
view.registerObserver(pathRoot, path + '.' + dependentKeys[i], observer);
}
});
};

Expand Down
27 changes: 7 additions & 20 deletions packages/ember-handlebars/lib/helpers/binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,7 @@ function bind(property, options, preserveContext, shouldDisplay, valueNormalizer
// is an empty string, we are printing the current context
// object ({{this}}) so updating it is not our responsibility.
if (path !== '') {
Ember.addObserver(pathRoot, path, observer);

view.one('willClearRender', function() {
Ember.removeObserver(pathRoot, path, observer);
});
view.registerObserver(pathRoot, path, observer);
}
} else {
// The object is not observable, so just render it out and
Expand Down Expand Up @@ -130,11 +126,7 @@ function simpleBind(property, options) {
// is an empty string, we are printing the current context
// object ({{this}}) so updating it is not our responsibility.
if (path !== '') {
Ember.addObserver(pathRoot, path, observer);

view.one('willClearRender', function() {
Ember.removeObserver(pathRoot, path, observer);
});
view.registerObserver(pathRoot, path, observer);
}
} else {
// The object is not observable, so just render it out and
Expand Down Expand Up @@ -228,6 +220,9 @@ EmberHandlebars.registerHelper('bind', function(property, options) {
EmberHandlebars.registerHelper('boundIf', function(property, fn) {
var context = (fn.contexts && fn.contexts[0]) || this;
var func = function(result) {
var truthy = result && get(result, 'isTruthy');
if (typeof truthy === 'boolean') { return truthy; }

if (Ember.typeOf(result) === 'array') {
return get(result, 'length') !== 0;
} else {
Expand Down Expand Up @@ -515,11 +510,7 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
// When the observer fires, find the element using the
// unique data id and update the attribute to the new value.
if (path !== 'this') {
Ember.addObserver(pathRoot, path, invoker);

view.one('willClearRender', function() {
Ember.removeObserver(pathRoot, path, invoker);
});
view.registerObserver(pathRoot, path, invoker);
}

// if this changes, also change the logic in ember-views/lib/views/view.js
Expand Down Expand Up @@ -638,11 +629,7 @@ EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId,
};

if (path !== '' && path !== 'this') {
Ember.addObserver(pathRoot, path, invoker);

view.one('willClearRender', function() {
Ember.removeObserver(pathRoot, path, invoker);
});
view.registerObserver(pathRoot, path, invoker);
}

// We've already setup the observer; now we just need to figure out the
Expand Down
30 changes: 29 additions & 1 deletion packages/ember-handlebars/tests/helpers/if_unless_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ var appendView = function(view) {
Ember.run(function() { view.appendTo('#qunit-fixture'); });
};

var compile = Ember.Handlebars.compile;

var view;

module("Handlebars {{#if}} and {{#unless}} helpers", {
Expand All @@ -18,10 +20,36 @@ test("unless should keep the current context (#784)", function() {
view = Ember.View.create({
o: Ember.Object.create({foo: '42'}),

template: Ember.Handlebars.compile('{{#with view.o}}{{#view Ember.View}}{{#unless view.doesNotExist}}foo: {{foo}}{{/unless}}{{/view}}{{/with}}')
template: compile('{{#with view.o}}{{#view Ember.View}}{{#unless view.doesNotExist}}foo: {{foo}}{{/unless}}{{/view}}{{/with}}')
});

appendView(view);

equal(view.$().text(), 'foo: 42');
});

test("The `if` helper tests for `isTruthy` if available", function() {
view = Ember.View.create({
truthy: Ember.Object.create({ isTruthy: true }),
falsy: Ember.Object.create({ isTruthy: false }),

template: compile('{{#if view.truthy}}Yep{{/if}}{{#if view.falsy}}Nope{{/if}}')
});

appendView(view);

equal(view.$().text(), 'Yep');
});

test("The `if` helper does not print the contents for an object proxy without content", function() {
view = Ember.View.create({
truthy: Ember.ObjectProxy.create({ content: {} }),
falsy: Ember.ObjectProxy.create({ content: null }),

template: compile('{{#if view.truthy}}Yep{{/if}}{{#if view.falsy}}Nope{{/if}}')
});

appendView(view);

equal(view.$().text(), 'Yep');
});
113 changes: 113 additions & 0 deletions packages/ember-handlebars/tests/lookup_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module("Ember.Handlebars.resolveParams");

test("Raw string parameters should be returned as Strings", function() {
var params = Ember.Handlebars.resolveParams({}, ["foo", "bar", "baz"], { types: ["STRING", "STRING", "STRING"] });
deepEqual(params, ["foo", "bar", "baz"]);
});

test("Raw boolean parameters should be returned as Booleans", function() {
var params = Ember.Handlebars.resolveParams({}, [true, false], { types: ["BOOLEAN", "BOOLEAN"] });
deepEqual(params, [true, false]);
});

test("Raw numeric parameters should be returned as Numbers", function() {
var params = Ember.Handlebars.resolveParams({}, [1, 1.0, 1.5, 0.5], { types: ["NUMBER", "NUMBER", "NUMBER", "NUMBER"] });
deepEqual(params, [1, 1, 1.5, 0.5]);
});

test("ID parameters should be looked up on the context", function() {
var context = {
salutation: "Mr",
name: {
first: "Tom",
last: "Dale"
}
};

var params = Ember.Handlebars.resolveParams(context, ["salutation", "name.first", "name.last"], { types: ["ID", "ID", "ID"] });
deepEqual(params, ["Mr", "Tom", "Dale"]);
});

test("ID parameters can look up keywords", function() {
var controller = {
salutation: "Mr"
};

var view = {
name: { first: "Tom", last: "Dale" }
};

var context = {
yuno: "State Charts"
};

var options = {
types: ["ID", "ID", "ID", "ID"],
data: {
keywords: {
controller: controller,
view: view
}
}
};

var params = Ember.Handlebars.resolveParams(context, ["controller.salutation", "view.name.first", "view.name.last", "yuno"], options);
deepEqual(params, ["Mr", "Tom", "Dale", "State Charts"]);
});

module("Ember.Handlebars.resolveHash");

test("Raw string parameters should be returned as Strings", function() {
var hash = Ember.Handlebars.resolveHash({}, { string: "foo" }, { hashTypes: { string: "STRING" } });
deepEqual(hash, { string: "foo" });
});

test("Raw boolean parameters should be returned as Booleans", function() {
var hash = Ember.Handlebars.resolveHash({}, { yes: true, no: false }, { hashTypes: { yes: "BOOLEAN", no: "BOOLEAN" } });
deepEqual(hash, { yes: true, no: false });
});

test("Raw numeric parameters should be returned as Numbers", function() {
var hash = Ember.Handlebars.resolveHash({}, { one: 1, oneFive: 1.5, ohFive: 0.5 }, { hashTypes: { one: "NUMBER", oneFive: "NUMBER", ohFive: "NUMBER" } });
deepEqual(hash, { one: 1, oneFive: 1.5, ohFive: 0.5 });
});

test("ID parameters should be looked up on the context", function() {
var context = {
salutation: "Mr",
name: {
first: "Tom",
last: "Dale"
}
};

var hash = Ember.Handlebars.resolveHash(context, { mr: "salutation", firstName: "name.first", lastName: "name.last" }, { hashTypes: { mr: "ID", firstName: "ID", lastName: "ID" } });
deepEqual(hash, { mr: "Mr", firstName: "Tom", lastName: "Dale" });
});

test("ID parameters can look up keywords", function() {
var controller = {
salutation: "Mr"
};

var view = {
name: { first: "Tom", last: "Dale" }
};

var context = {
yuno: "State Charts"
};

var options = {
hashTypes: { mr: "ID", firstName: "ID", lastName: "ID", yuno: "ID" },
data: {
keywords: {
controller: controller,
view: view
}
}
};

var hash = Ember.Handlebars.resolveHash(context, { mr: "controller.salutation", firstName: "view.name.first", lastName: "view.name.last", yuno: "yuno" }, options);
deepEqual(hash, { mr: "Mr", firstName: "Tom", lastName: "Dale", yuno: "State Charts" });
});
18 changes: 11 additions & 7 deletions packages/ember-routing/lib/helpers/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require('ember-handlebars/helpers/view');

Ember.onLoad('Ember.Handlebars', function(Handlebars) {

var resolvePaths = Ember.Handlebars.resolvePaths,
var resolveParams = Ember.Handlebars.resolveParams,
isSimpleClick = Ember.ViewUtils.isSimpleClick;

var EmberHandlebars = Ember.Handlebars,
Expand All @@ -21,7 +21,11 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
function args(options, actionName) {
var ret = [];
if (actionName) { ret.push(actionName); }
return ret.concat(resolvePaths(options.parameters));

var types = options.options.types.slice(1),
data = options.options.data;

return ret.concat(resolveParams(options.context, options.params, { types: types, data: data }));
}

var ActionHelper = EmberHandlebars.ActionHelper = {
Expand All @@ -46,10 +50,10 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
target = options.target;

if (target.send) {
return target.send.apply(target, args(options, actionName));
return target.send.apply(target, args(options.parameters, actionName));
} else {
Ember.assert("The action '" + actionName + "' did not exist on " + target, typeof target[actionName] === 'function');
return target[actionName].apply(target, args(options));
return target[actionName].apply(target, args(options.parameters));
}
}
};
Expand Down Expand Up @@ -247,9 +251,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
};

action.parameters = {
data: options.data,
contexts: contexts,
roots: options.contexts
context: this,
options: options,
params: contexts
};

action.view = view = get(view, 'concreteView');
Expand Down
Loading