Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

can-stache-bindings

Package Overview
Dependencies
Maintainers
10
Versions
219
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

can-stache-bindings - npm Package Compare versions

Comparing version 3.6.3 to 3.7.0

156

can-stache-bindings.js

@@ -390,2 +390,10 @@ // # can-stache-bindings.js

// check for `on:event:value:to` type things and call data bindings
if(attributeName.indexOf(toMatchStr+":") !== -1 ||
attributeName.indexOf(fromMatchStr+":") !== -1 ||
attributeName.indexOf(bindMatchStr+":") !== -1
) {
return this.data(el, data);
}
// legacy binding

@@ -655,5 +663,12 @@ if(startsWith.call(attributeName, 'can-')) {

viewCallbacks.attr(/^(:lb:)[(:c:)\w-]+(:rb:)$/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:to/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:from/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:bind/, behaviors.data);
// value:to="bar" data bindings
// these are separate so that they only capture at the end
// to avoid (toggle)="bar" which is encoded as :lp:toggle:rp:="bar"
viewCallbacks.attr(/[\w\.:]+:to$/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:from$/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:bind$/, behaviors.data);
// value:to:on:input="bar" data bindings
viewCallbacks.attr(/[\w\.:]+:to:on:[\w\.:]+/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:from:on:[\w\.:]+/, behaviors.data);
viewCallbacks.attr(/[\w\.:]+:bind:on:[\w\.:]+/, behaviors.data);

@@ -899,6 +914,56 @@ // `*ref-export` shorthand.

};
var endsWith = String.prototype.endsWith || function(text){
var lastIndex = this.lastIndexOf(text);
return lastIndex !== -1 && lastIndex === (this.length - text.length);
// Gets an event name in the after part.
function getEventName(result) {
if(result.special.on !== undefined) {
return result.tokens[result.special.on+1];
}
}
var bindingRules = {
to: {
childToParent: true,
parentToChild: false,
syncChildWithParent: false
},
from: {
childToParent: false,
parentToChild: true,
syncChildWithParent: false,
},
bind: {
childToParent: true,
parentToChild: true,
syncChildWithParent: true,
}
};
var bindingNames = [];
var special = {
vm: true,
on: true
};
each(bindingRules, function(value, key){
bindingNames.push(key);
special[key] = true;
});
// "on:click:value:to" //-> {tokens: [...], special: {on: 0, to: 3}}
function tokenize(source) {
var splitByColon = source.split(":");
// combine tokens that are not to, from, vm,
var result = {
tokens: [],
special: {}
};
splitByColon.forEach(function(token){
if(special[token]) {
result.special[token] = result.tokens.push(token) - 1;
} else {
result.tokens.push(token);
}
});
return result;
}
// Regular expressions for getBindingInfo

@@ -911,2 +976,13 @@ var bindingsRegExp = /\{(\()?(\^)?([^\}\)]+)\)?\}/,

// ## getChildBindingStr
var getChildBindingStr = function(tokens, favorViewModel) {
if (tokens.indexOf('vm') >= 0) {
return viewModelBindingStr;
} else if (tokens.indexOf('el') >= 0) {
return attributeBindingStr;
} else {
return favorViewModel ? viewModelBindingStr: viewModelOrAttributeBindingStr;
}
};
// ## getBindingInfo

@@ -926,3 +1002,2 @@ // takes a node object like {name, value} and returns

var getBindingInfo = function(node, attributeViewModelBindings, templateType, tagName, favorViewModel) {
var bindingInfo,

@@ -933,44 +1008,31 @@ attributeName = encoder.decode( node.name ),

// check new binding syntaxes
if(endsWith.call(attributeName, fromMatchStr)) {
childName = attributeName.substr(0, attributeName.length - fromMatchStr.length);
return {
// START: check new binding syntaxes ======
var result = tokenize(attributeName),
dataBindingName,
specialIndex;
// check if there's a match of a binding name with at least a value before it
bindingNames.forEach(function(name){
if(result.special[name] !== undefined && result.special[name] > 0) {
dataBindingName = name;
specialIndex = result.special[name];
return false;
}
});
if(dataBindingName) {
return assign({
parent: scopeBindingStr,
child: favorViewModel ? viewModelBindingStr: viewModelOrAttributeBindingStr,
childToParent: false,
parentToChild: true,
child: getChildBindingStr(result.tokens, favorViewModel),
// the child is going to be the token before the special location
childName: result.tokens[specialIndex-1],
childEvent: getEventName(result),
bindingAttributeName: attributeName,
childName: decodeAttrName(string.camelize(childName)),
parentName: attributeValue,
initializeValues: true,
syncChildWithParent: false
};
} else if(endsWith.call(attributeName, toMatchStr)) {
childName = attributeName.substr(0, attributeName.length - toMatchStr.length);
return {
parent: scopeBindingStr,
child: favorViewModel ? viewModelBindingStr: viewModelOrAttributeBindingStr,
childToParent: true,
parentToChild: false,
bindingAttributeName: attributeName,
childName: decodeAttrName(string.camelize(childName)),
parentName: attributeValue,
initializeValues: true,
syncChildWithParent: false
};
} else if(endsWith.call(attributeName, bindMatchStr)) {
childName = attributeName.substr(0, attributeName.length - bindMatchStr.length);
return {
parent: scopeBindingStr,
child: favorViewModel ? viewModelBindingStr: viewModelOrAttributeBindingStr,
childToParent: true,
parentToChild: true,
bindingAttributeName: attributeName,
childName: decodeAttrName(string.camelize(childName)),
parentName: attributeValue,
initializeValues: true,
syncChildWithParent: true
};
initializeValues: true
}, bindingRules[dataBindingName]);
}
// END: check new binding syntaxes ======
// Does this match the new binding syntax?

@@ -1107,3 +1169,4 @@ var matches = attributeName.match(bindingsRegExp);

bindingInfo.parentName,
bindingData, bindingInfo.parentToChild
bindingData,
bindingInfo.parentToChild
),

@@ -1116,3 +1179,4 @@ childObservable = getObservableFrom[bindingInfo.child](

bindingInfo.childToParent,
bindingInfo.stickyParentToChild && parentObservable
bindingInfo.stickyParentToChild && parentObservable,
bindingInfo.childEvent
),

@@ -1119,0 +1183,0 @@ // these are the functions bound to one compute that update the other.

@@ -60,2 +60,4 @@ @module can-stache-bindings

You can also explicitly use the [can-component::ViewModel ViewModel] using `vm:childProp:from="value"` or the element using `el:child-attr:from="value"`.
> __Note:__ If value being passed to the component is an object, changes to the objects properties will still be visible to the component. Objects are passed by reference. See [can-stache-bindings#OneWayBindingWithObjects One Way Binding With Objects].

@@ -81,2 +83,4 @@

You can also explicitly use the [can-component::ViewModel ViewModel] using `vm:childProp:to="value"` or the element using `el:child-attr:to="value"`.
> __Note:__ If value being passed to the component is an object, changes to the objects properties will still be visible to the component. Objects are passed by reference. See [can-stache-bindings#OneWayBindingWithObjects One Way Binding With Objects].

@@ -99,2 +103,4 @@

You can also explicitly use the [can-component::ViewModel ViewModel] using `vm:childProp:bind="value"` or the element using `el:child-attr:bind="value"`.
## One Way Binding With Objects

@@ -101,0 +107,0 @@

@@ -67,3 +67,45 @@ @function can-stache-bindings.event on:event

@signature `on:SCOPE_EVENT:by:this='CALL_EXPRESSION'`
Listens to an event on the [can-view-scope scope] and calls the [can-stache/expressions/call] when that event occurs.
```
<my-component on:show:by:this="doSomething()"/>
```
@param {String} SCOPE_EVENT a scope event.
@param {can-stache.expressions} CALL_EXPRESSION A call expression like `method(key)` that is called when the `VIEW_MODEL_EVENT`
is fired. The following key values are also supported:
- `%element` - The element the event happened upon.
- `%event` - The event object.
- `%viewModel` - If the element is a [can-component], the component’s [can-component::ViewModel ViewModel].
- `%context` - The current context.
- `%scope` - The current [can-view-scope].
- `%arguments` - The arguments passed when the event was dispatched/triggered.
@signature `on:SCOPE_PROP_EVENT:by:SCOPE_PROP='CALL_EXPRESSION'`
Listens to an event on a property of the [can-view-scope scope] and calls the [can-stache/expressions/call] when that event occurs.
```
<my-component on:show:by:obj="doSomething()"/>
```
@param {String} SCOPE_PROP_EVENT an event triggered by a scope property.
@param {String} SCOPE_PROP a scope property.
@param {can-stache.expressions} CALL_EXPRESSION A call expression like `method(key)` that is called when the `VIEW_MODEL_EVENT`
is fired. The following key values are also supported:
- `%element` - The element the event happened upon.
- `%event` - The event object.
- `%viewModel` - If the element is a [can-component], the component’s [can-component::ViewModel ViewModel].
- `%context` - The current context.
- `%scope` - The current [can-view-scope].
- `%arguments` - The arguments passed when the event was dispatched/triggered.
@body

@@ -70,0 +112,0 @@

@function can-stache-bindings.toChild toChild:from
@parent can-stache-bindings.syntaxes 1
@description One-way bind a value in the parent scope to the [can-component.prototype.ViewModel ViewModel].
@description One-way bind a value in the parent scope to the [can-component.prototype.ViewModel ViewModel] or element.

@@ -35,2 +35,31 @@ @signature `childProp:from="key"`

@signature `vm:childProp:from="key"`
Imports [can-stache.key] in the [can-view-scope scope] to `childProp` in [can-component.prototype.view-model viewModel]. It also updates `childProp` with the value of `key` when `key` changes.
```
<my-component vm:someProp:from="value"/>
```
> __Note:__ If [can-stache.key] is an object, changes to the objects properties will still be visible to the component. Objects are passed by reference. See [can-stache-bindings#OneWayBindingWithObjects One Way Binding With Objects].
@param {String} childProp The name of the property to set in the
component’s viewmodel.
@param {can-stache/expressions/literal|can-stache/expressions/key-lookup|can-stache/expressions/call|can-stache/expressions/helper} key An expression whose resulting value is used to set as `childProp`.
@signature `el:child-prop:from="key"`
Imports [can-stache.key] in the [can-view-scope scope] to `child-prop` property or attribute on the element.
```
<input el:value:from="name"/>
```
This signature works, but the following should be used instead:
```
<input value="{{name}}"/>
```
@body

@@ -37,0 +66,0 @@

@function can-stache-bindings.toParent toParent:to
@parent can-stache-bindings.syntaxes 2
@description One-way bind a value in the current [can-component.prototype.view-model viewModel] to the parent scope.
@description One-way bind a value from the [can-component.prototype.view-model viewModel] or element to the parent scope.

@@ -35,3 +35,32 @@ @signature `childProp:to="key"`

@signature `vm:childProp:to="key"`
Exports `childProp` in the [can-component.prototype.ViewModel ViewModel] to [can-stache.key] in the parent [can-view-scope scope]. It also updates
`key` with the value of `childProp` when `childProp` changes.
```
<my-component vm:someProp:to="value"/>
```
> __Note:__ If [can-stache.key] is an object, changes to the objects properties will still be visible to the component. Objects are passed by reference. See [can-stache-bindings#OneWayBindingWithObjects One Way Binding With Objects].
@param {String} childProp The name of the property to export from the
child components viewmodel. Use `this:to` or `.:to` to export the entire viewModel.
@param {can-stache/expressions/literal|can-stache/expressions/key-lookup|can-stache/expressions/call|can-stache/expressions/helper} key An expression that will be used to set in the parent scope.
@signature `el:child-prop:to="key"`
Exports the element’s `child-prop` property or attribute to [can-stache.key] in the parent [can-view-scope scope]. It also updates
`key` with the value of `child-prop` when `child-prop` changes.
```
<input el:value:to="name"/>
```
@param {String} child-prop The name of the element’s property or attribute to export.
@param {can-stache/expressions/literal|can-stache/expressions/key-lookup|can-stache/expressions/call|can-stache/expressions/helper} key An expression whose resulting value with be used to set in the parent scope.
@body

@@ -38,0 +67,0 @@

@@ -42,2 +42,38 @@ @function can-stache-bindings.twoWay twoWay:bind

@signature `vm:childProp:bind="key"`
Two-way binds `childProp` in the [can-component.prototype.ViewModel ViewModel] to
[can-stache.key] in the parent [can-view-scope scope]. If `childProp` is updated `key` will be updated
and vice-versa.
```
<my-component vm:someProp:bind="value"/>
```
When setting up the binding:
- If `childProp` is `undefined`, `key` will be set to `childProp`.
- If `key` is `undefined`, `childProp` will be set to `key`.
- If both `childProp` and `key` are defined, `key` will be set to `childProp`.
@param {String} childProp The name of the property of the viewModel to two-way bind.
@param {can-stache/expressions/literal|can-stache/expressions/key-lookup|can-stache/expressions/call|can-stache/expressions/helper} key A call expression whose value will be used to two-way bind in the parent scope.
@signature `el:child-prop:bind="key"`
Two-way binds the element’s `child-prop` property or attribute to
[can-stache.key] in the parent [can-view-scope scope]. If `child-prop` is updated `key` will be updated
and vice-versa.
```
<input el:value:bind="name"/>
```
@param {String} child-prop The name of the element’s property or attribute to two-way bind.
@param {can-stache/expressions/literal|can-stache/expressions/key-lookup|can-stache/expressions/call|can-stache/expressions/helper} key A call expression whose value will be used to two-way bind in the parent scope.
@body

@@ -44,0 +80,0 @@

{
"name": "can-stache-bindings",
"version": "3.6.3",
"version": "3.7.0",
"description": "Default binding syntaxes for can-stache",

@@ -5,0 +5,0 @@ "homepage": "http://canjs.com",

@@ -146,5 +146,6 @@ var QUnit = require("steal-qunit");

child: "viewModelOrAttribute",
childEvent: undefined,
parentToChild: true,
childToParent: false,
childName: "fooEd",
childName: "foo-ed",
parentName: "bar",

@@ -154,3 +155,3 @@ bindingAttributeName: "foo-ed:from",

syncChildWithParent: false
}, "new vm binding");
}, ":from");

@@ -161,5 +162,6 @@ info = stacheBindings.getBindingInfo({name: "foo-ed:bind", value: "bar"});

child: "viewModelOrAttribute",
childEvent: undefined,
parentToChild: true,
childToParent: true,
childName: "fooEd",
childName: "foo-ed",
parentName: "bar",

@@ -169,3 +171,3 @@ bindingAttributeName: "foo-ed:bind",

syncChildWithParent: true
}, "new el binding");
}, ":bind");

@@ -176,5 +178,6 @@ info = stacheBindings.getBindingInfo({name: "foo-ed:to", value: "bar"});

child: "viewModelOrAttribute",
childEvent: undefined,
parentToChild: false,
childToParent: true,
childName: "fooEd",
childName: "foo-ed",
parentName: "bar",

@@ -184,3 +187,4 @@ bindingAttributeName: "foo-ed:to",

syncChildWithParent: false
}, "new el binding");
}, ":to");
info = stacheBindings.getBindingInfo({name: "foo-ed:from", value: "bar"}, null, null, null, true);

@@ -190,5 +194,6 @@ deepEqual(info, {

child: "viewModel",
childEvent: undefined,
parentToChild: true,
childToParent: false,
childName: "fooEd",
childName: "foo-ed",
parentName: "bar",

@@ -198,3 +203,3 @@ bindingAttributeName: "foo-ed:from",

syncChildWithParent: false
}, "new vm binding");
}, ":from, favorViewModel=true");

@@ -205,5 +210,6 @@ info = stacheBindings.getBindingInfo({name: "foo-ed:bind", value: "bar"}, null, null, null, true);

child: "viewModel",
childEvent: undefined,
parentToChild: true,
childToParent: true,
childName: "fooEd",
childName: "foo-ed",
parentName: "bar",

@@ -213,3 +219,3 @@ bindingAttributeName: "foo-ed:bind",

syncChildWithParent: true
}, "new el binding");
}, ":bind, favorViewModel=true");

@@ -220,5 +226,6 @@ info = stacheBindings.getBindingInfo({name: "foo-ed:to", value: "bar"}, null, null, null, true);

child: "viewModel",
childEvent: undefined,
parentToChild: false,
childToParent: true,
childName: "fooEd",
childName: "foo-ed",
parentName: "bar",

@@ -228,5 +235,177 @@ bindingAttributeName: "foo-ed:to",

syncChildWithParent: false
}, "new el binding");
}, ":to, favorViewModel=true");
});
test("getBindingInfo for vm:", function() {
var info = stacheBindings.getBindingInfo({name: "vm:foo-ed:from", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "viewModel",
childEvent: undefined,
parentToChild: true,
childToParent: false,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "vm:foo-ed:from",
initializeValues: true,
syncChildWithParent: false
}, ":from");
info = stacheBindings.getBindingInfo({name: "vm:foo-ed:bind", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "viewModel",
childEvent: undefined,
parentToChild: true,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "vm:foo-ed:bind",
initializeValues: true,
syncChildWithParent: true
}, ":bind");
info = stacheBindings.getBindingInfo({name: "vm:foo-ed:to", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "viewModel",
childEvent: undefined,
parentToChild: false,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "vm:foo-ed:to",
initializeValues: true,
syncChildWithParent: false
}, ":to");
info = stacheBindings.getBindingInfo({name: "vm:foo-ed:from", value: "bar"}, null, null, null, true);
deepEqual(info, {
parent: "scope",
child: "viewModel",
childEvent: undefined,
parentToChild: true,
childToParent: false,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "vm:foo-ed:from",
initializeValues: true,
syncChildWithParent: false
}, ":from, favorViewModel=true");
info = stacheBindings.getBindingInfo({name: "vm:foo-ed:bind", value: "bar"}, null, null, null, true);
deepEqual(info, {
parent: "scope",
child: "viewModel",
childEvent: undefined,
parentToChild: true,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "vm:foo-ed:bind",
initializeValues: true,
syncChildWithParent: true
}, ":bind, favorViewModel=true");
info = stacheBindings.getBindingInfo({name: "vm:foo-ed:to", value: "bar"}, null, null, null, true);
deepEqual(info, {
parent: "scope",
child: "viewModel",
childEvent: undefined,
parentToChild: false,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "vm:foo-ed:to",
initializeValues: true,
syncChildWithParent: false
}, ":to, favorViewModel=true");
});
test("getBindingInfo for el:", function() {
var info = stacheBindings.getBindingInfo({name: "el:foo-ed:from", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "attribute",
childEvent: undefined,
parentToChild: true,
childToParent: false,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "el:foo-ed:from",
initializeValues: true,
syncChildWithParent: false
}, ":from");
info = stacheBindings.getBindingInfo({name: "el:foo-ed:bind", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "attribute",
childEvent: undefined,
parentToChild: true,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "el:foo-ed:bind",
initializeValues: true,
syncChildWithParent: true
}, ":bind");
info = stacheBindings.getBindingInfo({name: "el:foo-ed:to", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "attribute",
childEvent: undefined,
parentToChild: false,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "el:foo-ed:to",
initializeValues: true,
syncChildWithParent: false
}, ":to");
info = stacheBindings.getBindingInfo({name: "el:foo-ed:from", value: "bar"}, null, null, null, true);
deepEqual(info, {
parent: "scope",
child: "attribute",
childEvent: undefined,
parentToChild: true,
childToParent: false,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "el:foo-ed:from",
initializeValues: true,
syncChildWithParent: false
}, ":from, favorViewModel=true");
info = stacheBindings.getBindingInfo({name: "el:foo-ed:bind", value: "bar"}, null, null, null, true);
deepEqual(info, {
parent: "scope",
child: "attribute",
childEvent: undefined,
parentToChild: true,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "el:foo-ed:bind",
initializeValues: true,
syncChildWithParent: true
}, ":bind, favorViewModel=true");
info = stacheBindings.getBindingInfo({name: "el:foo-ed:to", value: "bar"}, null, null, null, true);
deepEqual(info, {
parent: "scope",
child: "attribute",
childEvent: undefined,
parentToChild: false,
childToParent: true,
childName: "foo-ed",
parentName: "bar",
bindingAttributeName: "el:foo-ed:to",
initializeValues: true,
syncChildWithParent: false
}, ":to, favorViewModel=true");
});
test("value:from works with camelCase and kebab-case properties", function() {

@@ -460,31 +639,2 @@ var template = stache(

test('can bind to property on viewModel using on:vm:prop:by:obj', function() {
stop();
expect(1);
var map = new SimpleMap({
obj: new SimpleMap({
prop: "Mercury"
})
});
var MySimpleMap = SimpleMap.extend({
someMethod: function(scope, el, ev, newVal){
start();
equal(newVal, "Venus", "method called");
}
});
var parent = new MySimpleMap();
MockComponent.extend({
tag: "view-model-able",
viewModel: map
});
var template = stache("<view-model-able on:vm:prop:by:obj='someMethod'/>");
template(parent);
map.attr("obj").attr("prop", "Venus");
});
test('can bind to element using on:el:prop', function() {

@@ -519,2 +669,44 @@ stop();

QUnit.test("getBindingInfo works for value:to:on:click (#269)", function(){
var info = stacheBindings.getBindingInfo({name: "value:to:on:click", value: "bar"});
deepEqual(info, {
parent: "scope",
child: "viewModelOrAttribute",
childEvent: "click",
parentToChild: false,
childToParent: true,
childName: "value",
parentName: "bar",
bindingAttributeName: "value:to:on:click",
initializeValues: true,
syncChildWithParent: false
}, "new vm binding");
});
test("value:to:on:click and on:click:value:to work (#269)", function() {
var template = stache(
"<input value:to:on:click='theProp'/>" +
"<input on:click:value:to='theProp'/>"
);
var map = new SimpleMap({});
var frag = template(map);
var ta = this.fixture;
ta.appendChild(frag);
var bindFirstInput = ta.getElementsByTagName("input")[0];
bindFirstInput.value = "22";
canEvent.trigger.call(bindFirstInput, "click");
QUnit.equal(map.get('theProp'), "22");
var eventFirstInput = ta.getElementsByTagName("input")[1];
eventFirstInput.value = "23";
canEvent.trigger.call(eventFirstInput, "click");
QUnit.equal(map.get('theProp'), "23");
});
QUnit.test("on:el:click works inside {{#if}} on element with a viewModel (#279)", function() {

@@ -544,2 +736,112 @@ var map = new SimpleMap({

QUnit.test("vm:prop:to/:from/:bind work (#280)", function() {
var vm1 = new SimpleMap({ value: 'vm1' });
var vm2 = new SimpleMap({ value: 'vm2' });
var vm3 = new SimpleMap({ value: 'vm3' });
MockComponent.extend({
tag: "comp-1",
viewModel: vm1
});
MockComponent.extend({
tag: "comp-2",
viewModel: vm2
});
MockComponent.extend({
tag: "comp-3",
viewModel: vm3
});
var template = stache(
"<comp-1 vm:value:to='scope1'/>" +
"<comp-2 vm:value:from='scope2'/>" +
"<comp-3 vm:value:bind='scope3'/>"
);
var scope = new SimpleMap({
scope1: 'scope1',
scope2: 'scope2',
scope3: 'scope3'
});
template(scope);
// vm:value:to
equal(scope.attr('scope1'), 'vm1', 'vm:value:to - scope value set from vm');
vm1.attr('value', 'vm4');
equal(scope.attr('scope1'), 'vm4', 'vm:value:to - scope updated when vm changes');
scope.attr('scope1', 'scope4');
equal(vm1.attr('value'), 'vm4', 'vm:value:to - vm not updated when scope changes');
// vm:value:from
equal(vm2.attr('value'), 'scope2', 'vm:value:from - vm value set from scope');
scope.attr('scope2', 'scope5');
equal(vm2.attr('value'), 'scope5', 'vm:value:from - vm updated when scope changes');
vm2.attr('value', 'vm5');
equal(scope.attr('scope2'), 'scope5', 'vm:value:from - scope not updated when vm changes');
// vm:value:bind
equal(vm3.attr('value'), 'scope3', 'vm:value:bind - vm value set from scope');
scope.attr('scope3', 'scope6');
equal(vm3.attr('value'), 'scope6', 'vm:value:bind - vm updated when scope changes');
vm3.attr('value', 'vm6');
equal(scope.attr('scope3'), 'vm6', 'vm:value:bind - scope updated when vm changes');
});
QUnit.test('el:prop:to/:from/:bind work (#280)', function() {
var template = stache(
"<input el:value:to='scope1' value='1'/>" +
"<input el:value:from='scope2' value='2'/>" +
"<input el:value:bind='scope3' value='3'/>"
);
var scope = new SimpleMap({
scope1: 'scope1',
scope2: 'scope2',
scope3: 'scope3'
});
var frag = template(scope);
var ta = this.fixture;
ta.appendChild(frag);
var inputTo = ta.getElementsByTagName('input')[0];
var inputFrom = ta.getElementsByTagName('input')[1];
var inputBind = ta.getElementsByTagName('input')[2];
// el:value:to
equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute');
inputTo.value = '4';
canEvent.trigger.call(inputTo, 'change');
equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed');
scope.attr('scope1', 'scope4');
equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed');
// el:value:from
equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope');
inputFrom.value = 'scope5';
canEvent.trigger.call(inputFrom, 'change');
equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed');
scope.attr('scope2', 'scope6');
equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed');
// el:value:bind
equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)');
inputBind.value = 'scope6';
canEvent.trigger.call(inputBind, 'change');
equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed');
scope.attr('scope3', 'scope7');
equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed');
});
}

@@ -467,1 +467,39 @@ var bindings = require('can-stache-bindings');

});
QUnit.test("events starting with `to`, `from`, and `bind` work (#285)", function() {
expect(3);
var ViewModel = DefineMap.extend({
toevent: '1',
fromevent: '1',
bindevent: '1',
});
MockComponent.extend({
tag: 'view-model-able',
viewModel: ViewModel
});
var template = stache("<view-model-able (toevent)='toMethod()' (fromevent)='fromMethod()' (bindevent)='bindMethod()' />");
var Parent = DefineMap.extend({
toMethod: function() {
QUnit.ok(true, '(toevent) worked');
},
fromMethod: function() {
QUnit.ok(true, '(fromevent) worked');
},
bindMethod: function() {
QUnit.ok(true, '(bindevent) worked');
}
});
var parent = new Parent();
var frag = template(parent);
var el = frag.firstChild;
var vm = canViewModel(el);
vm.toevent = '2';
vm.fromevent = '2';
vm.bindevent = '2';
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc