Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stache subexpressions #1832

Merged
merged 9 commits into from
Aug 8, 2015
Merged
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: 1 addition & 1 deletion compute/read.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading