Skip to content

Commit

Permalink
Merge pull request #1832 from bitovi/subexpressions-1769
Browse files Browse the repository at this point in the history
Stache subexpressions
  • Loading branch information
daffl committed Aug 8, 2015
2 parents aecf050 + f9444af commit a8bcaeb
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 180 deletions.
2 changes: 1 addition & 1 deletion compute/read.js
Expand Up @@ -114,7 +114,7 @@ steal("can/util", function(can){
if (options.isArgument && i === reads.length) {
return options.proxyMethods !== false ? can.proxy(value, prev) : value;
}
return value.call(prev);
return value.apply(prev, options.args || []);
}
}];

Expand Down
24 changes: 24 additions & 0 deletions util/zepto/zepto.js
Expand Up @@ -66,6 +66,30 @@ steal('can/util/can.js', 'can/util/attr', 'can/event', 'zepto', 'can/util/object
can.each = oldEach;
can.attr = attr;
can.event = event;
function likeArray(obj) { return typeof obj.length === 'number'; }
can.map = function(elements, callback) {
var value, values = [], i, key;
if (likeArray(elements)) {
for ( i = 0; i < elements.length; i++) {
value = callback(elements[i], i);
if (value != null) {
values.push(value);
}
}
} else {
for (key in elements) {
value = callback(elements[key], key);
if (value != null) {
values.push(value);
}

}
}
return values;
};



var arrHas = function (obj, name) {
return obj[0] && obj[0][name] || obj[name];
};
Expand Down
32 changes: 28 additions & 4 deletions view/bindings/bindings.js
Expand Up @@ -188,7 +188,7 @@ steal("can/util", "can/view/stache/mustache_core.js", "can/view/callbacks", "can

// We grab the first item and treat it as a method that
// we'll call.
var scopeData = data.scope.read(attrInfo.name.get, {
var scopeData = data.scope.read(attrInfo.name.key, {
returnObserveMethods: true,
isArgument: true,
executeAnonymousFunctions: true
Expand All @@ -207,17 +207,40 @@ steal("can/util", "can/view/stache/mustache_core.js", "can/view/callbacks", "can
}
//!steal-remove-end

var args = [];
var $el = can.$(this);
var viewModel = can.viewModel($el[0]);

// make a scope with these things just under

var localScope = data.scope.add({
"@element": $el,
"@event": ev,
"@viewModel": viewModel,
"@scope": data.scope,
"@context": data.scope._context
},{
notContext: true
});

var convertToValue = function(arg){
if(typeof arg === "function" && arg.isComputed) {
return convertToValue( arg() );
} else {
return arg;
}
};

var args = can.map( attrInfo.args(localScope), convertToValue),
hash = {},
hasHash;

can.each( attrInfo.hash(localScope), function(value, name){
hasHash = true;
hash[name] = convertToValue(value);
});
if(hasHash) {
args.push(hash);
}
/*
// .expressionData() gives us a hash object representing
// any expressions inside the definition that look like
// foo=bar. If there's no hash keys, we'll omit this hash
Expand Down Expand Up @@ -248,7 +271,8 @@ steal("can/util", "can/view/stache/mustache_core.js", "can/view/callbacks", "can
args.unshift(arg);
}
}
}
}*/

// If no arguments are provided, the method will simply
// receive the legacy arguments.
if (!args.length) {
Expand Down
17 changes: 11 additions & 6 deletions view/href/href.js
Expand Up @@ -19,14 +19,19 @@ steal("can/util",
var attrInfo = mustacheCore.expressionData('tmp ' + removeCurly(el.getAttribute("can-href")));
// -> {hash: {foo: 'bar', zed: 5, abc: {get: 'myValue'}}}

var convertToValue = function(arg){
if(typeof arg === "function" && arg.isComputed) {
return convertToValue( arg() );
} else {
return arg;
}
};

var routeHref = can.compute(function(){
var hash = {};
can.each(attrInfo.hash, function(val, key) {
if (val && val.hasOwnProperty("get")) {
hash[key] = attrData.scope.read(val.get, {}).value;
} else {
hash[key] = val;
}

can.each(attrInfo.hash(attrData.scope), function(val, key) {
hash[key] = convertToValue(val);
});
return can.route.url(hash);
});
Expand Down
21 changes: 17 additions & 4 deletions view/scope/scope.js
Expand Up @@ -214,25 +214,38 @@ steal(
if(this._meta.protected) {
return this._parent.read(attr, options);
}
var isInCurrentContext = attr.substr(0, 2) === './',
isInParentContext = attr.substr(0, 3) === "../",
isCurrentContext = attr === "." || attr === "this",
isParentContext = attr === "..",
isContextBased = isInCurrentContext ||
isInParentContext ||
isCurrentContext ||
isParentContext;

// notContent items can be read, but are skipped if you are doing .. sorta stuff.
if(isContextBased && this._meta.notContext) {
return this._parent.read(attr, options);
}

// check if we should only look within current scope
var stopLookup;
if(attr.substr(0, 2) === './') {
if(isInCurrentContext) {
// set flag to halt lookup from walking up scope
stopLookup = true;
// stop lookup from checking parent scopes
attr = attr.substr(2);
}
// check if we should be running this on a parent.
else if (attr.substr(0, 3) === "../") {
else if (isInParentContext) {
return this._parent.read(attr.substr(3), options);
}
else if (attr === "." || attr === "this") {
else if ( isCurrentContext ) {
return {
value: this._context
};
}
else if (attr === "..") {
else if ( isParentContext ) {
return {
value: this._parent._context
};
Expand Down

0 comments on commit a8bcaeb

Please sign in to comment.