Skip to content

Commit 8e3e41e

Browse files
committed
feat: Mapping function for binders atttr, dataset, html, prop, style, text
1 parent 03b8bba commit 8e3e41e

File tree

7 files changed

+83
-25
lines changed

7 files changed

+83
-25
lines changed

src/binders/attr.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// returns a binder for element attribute
2-
export default function attr(attributeName) {
2+
export default function attr(attributeName, mappingFn) {
33
return {
44
on: null,
55
getValue() {
66
return this.getAttribute(attributeName);
77
},
88
setValue(value) {
9-
this.setAttribute(attributeName, value);
9+
const val = typeof mappingFn === 'function' ? mappingFn(value) : value;
10+
this.setAttribute(attributeName, val);
1011
}
1112
};
1213
}

src/binders/dataset.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const toDashed = name => `data-${name.replace(/([A-Z])/g, replacer)}`;
44

55
// returns a binder for dataset of an element
66
// old browsers are also supported @IE9 @IE10
7-
export default function dataset(prop) {
7+
export default function dataset(prop, mappingFn) {
88
return {
99
on: null,
1010
getValue() {
@@ -15,10 +15,12 @@ export default function dataset(prop) {
1515
return this.getAttribute(toDashed(prop));
1616
},
1717
setValue(value) {
18+
const val = typeof mappingFn === 'function' ? mappingFn(value) : value;
19+
1820
if (this.dataset) {
19-
this.dataset[prop] = value;
21+
this.dataset[prop] = val;
2022
} else {
21-
this.setAttribute(toDashed(prop), value);
23+
this.setAttribute(toDashed(prop), val);
2224
}
2325
}
2426
};

src/binders/html.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// returns a binder for innerHTML of an element
2-
export default function html() {
2+
export default function html(mappingFn) {
33
return {
44
on: 'input', // the event name fires only in contenteditable mode
55
getValue() {
66
return this.innerHTML;
77
},
88
setValue(value) {
9-
this.innerHTML = `${value}`;
9+
const val = typeof mappingFn === 'function' ? mappingFn(value) : value;
10+
this.innerHTML = `${val}`;
1011
}
1112
};
1213
}

src/binders/prop.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// returns a binder to change properties of an element
2-
export default function prop(propertyName) {
2+
export default function prop(propertyName, mappingFn) {
33
return {
44
on: null,
55
getValue() {
66
return this[propertyName];
77
},
88
setValue(value) {
9+
const val = typeof mappingFn === 'function' ? mappingFn(value) : value;
910
// in case when you're trying to set read-only property
1011
try {
11-
this[propertyName] = value;
12+
this[propertyName] = val;
1213
} catch (e) {
1314
// cannot set given property (eg tagName)
1415
}

src/binders/style.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
// returns a binder for style properties
2-
export default function style(property) {
2+
export default function style(property, mappingFn) {
33
return {
44
on: null,
55
getValue() {
66
return this.style[property]
77
|| window.getComputedStyle(this).getPropertyValue(property);
88
},
99
setValue(value) {
10-
this.style[property] = value;
10+
const val = typeof mappingFn === 'function' ? mappingFn(value) : value;
11+
this.style[property] = val;
1112
}
1213
};
1314
}

src/binders/text.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// returns a binder for textContent of an element
2-
export default function text() {
2+
export default function text(mappingFn) {
33
return {
44
on: 'input', // the event name fires only in contenteditable mode
55
getValue() {
66
return this.textContent;
77
},
88
setValue(value) {
9-
this.textContent = `${value}`;
9+
const val = typeof mappingFn === 'function' ? mappingFn(value) : value;
10+
this.textContent = `${val}`;
1011
}
1112
};
1213
}

test/spec/bindings/binders_spec.js

+63-12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ describe('Binders', () => {
1717
debounceGetValue: false
1818
};
1919

20+
const mappingFn = value => `mapping_${value}`;
21+
2022
let obj;
2123
let node;
2224

@@ -33,14 +35,30 @@ describe('Binders', () => {
3335
expect(node.someProp).toEqual('bar');
3436
});
3537

38+
it('should bind prop and use mapping function', () => {
39+
node.someProp = 'foo';
40+
bindNode(obj, 'x', node, prop('someProp', mappingFn), noDebounceFlag);
41+
expect(obj.x).toEqual('foo');
42+
obj.x = 'bar';
43+
expect(node.someProp).toEqual('mapping_bar');
44+
});
45+
3646
it('should bind attr', () => {
3747
node.setAttribute('some-attribute', 'foo');
38-
bindNode(obj, 'x', node, attr('someProp'), noDebounceFlag);
39-
expect(node.getAttribute('some-attribute')).toEqual('foo');
40-
node.setAttribute('some-attribute', 'bar');
48+
bindNode(obj, 'x', node, attr('some-attribute'), noDebounceFlag);
49+
expect(obj.x).toEqual('foo');
50+
obj.x = 'bar';
4151
expect(node.getAttribute('some-attribute')).toEqual('bar');
4252
});
4353

54+
it('should bind attr and use mapping function', () => {
55+
node.setAttribute('some-attribute', 'foo');
56+
bindNode(obj, 'x', node, attr('some-attribute', mappingFn), noDebounceFlag);
57+
expect(obj.x).toEqual('foo');
58+
obj.x = 'bar';
59+
expect(node.getAttribute('some-attribute')).toEqual('mapping_bar');
60+
});
61+
4462
it('should bind html', () => {
4563
node.innerHTML = '<i>foo</i>';
4664
bindNode(obj, 'x', node, html(), noDebounceFlag);
@@ -49,6 +67,14 @@ describe('Binders', () => {
4967
expect(node.innerHTML).toEqual('<b>bar</b>');
5068
});
5169

70+
it('should bind html and use mapping function', () => {
71+
node.innerHTML = '<i>foo</i>';
72+
bindNode(obj, 'x', node, html(mappingFn), noDebounceFlag);
73+
expect(obj.x).toEqual('<i>foo</i>');
74+
obj.x = '<b>bar</b>';
75+
expect(node.innerHTML).toEqual('mapping_<b>bar</b>');
76+
});
77+
5278
it('should bind text', () => {
5379
node.textContent = '<i>foo</i>';
5480
bindNode(obj, 'x', node, text(), noDebounceFlag);
@@ -57,6 +83,14 @@ describe('Binders', () => {
5783
expect(node.textContent).toEqual('<b>bar</b>');
5884
});
5985

86+
it('should bind text and use mapping function', () => {
87+
node.textContent = '<i>foo</i>';
88+
bindNode(obj, 'x', node, text(mappingFn), noDebounceFlag);
89+
expect(obj.x).toEqual('<i>foo</i>');
90+
obj.x = '<b>bar</b>';
91+
expect(node.textContent).toEqual('mapping_<b>bar</b>');
92+
});
93+
6094
it('should bind style', () => {
6195
node.style.textAlign = 'center';
6296
bindNode(obj, 'x', node, style('textAlign'), noDebounceFlag);
@@ -65,6 +99,32 @@ describe('Binders', () => {
6599
expect(node.style.textAlign).toEqual('right');
66100
});
67101

102+
it('should bind style and use mapping function', () => {
103+
node.style.background = 'red';
104+
bindNode(obj, 'x', node, style('background', url => `url("${url}")`), noDebounceFlag);
105+
expect(obj.x).toEqual('red');
106+
obj.x = 'cats.jpg';
107+
expect(node.style.background).toEqual('url("cats.jpg")');
108+
});
109+
110+
it('should bind dataset', () => {
111+
// @IE9
112+
node.setAttribute('data-foo', 'bar');
113+
bindNode(obj, 'x', node, dataset('foo'), noDebounceFlag);
114+
expect(obj.x).toEqual('bar');
115+
obj.x = 'baz';
116+
expect(node.getAttribute('data-foo')).toEqual('baz');
117+
});
118+
119+
it('should bind dataset and use mapping function', () => {
120+
// @IE9
121+
node.setAttribute('data-foo', 'bar');
122+
bindNode(obj, 'x', node, dataset('foo', mappingFn), noDebounceFlag);
123+
expect(obj.x).toEqual('bar');
124+
obj.x = 'baz';
125+
expect(node.getAttribute('data-foo')).toEqual('mapping_baz');
126+
});
127+
68128
it('should bind display', () => {
69129
node.style.display = 'none';
70130
bindNode(obj, 'x', node, display(true), noDebounceFlag);
@@ -93,13 +153,4 @@ describe('Binders', () => {
93153
obj.x = true;
94154
expect(node.className).toEqual('');
95155
});
96-
97-
it('should bind dataset', () => {
98-
// @IE9
99-
node.setAttribute('data-foo', 'bar');
100-
bindNode(obj, 'x', node, dataset('foo'), noDebounceFlag);
101-
expect(obj.x).toEqual('bar');
102-
obj.x = 'baz';
103-
expect(node.getAttribute('data-foo')).toEqual('baz');
104-
});
105156
});

0 commit comments

Comments
 (0)