Skip to content

Commit f614dd6

Browse files
committed
bumps v0.13.0
1 parent d6b39e2 commit f614dd6

File tree

10 files changed

+94
-118
lines changed

10 files changed

+94
-118
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# 0.13.0 (2014-03-14)
2+
3+
## Breaking Changes
4+
5+
* replaces SyncMask by string mask. Use `attr: { ignore: 'CRU' }` in an attribute definition to specify if it should be considered when **C**reating, **U**pdating or **R**eading (d6b39e2)
6+
* makes properties that start with **$** private. Private properties are not consideren when encoding/decoding an object (2549845)
7+
8+
* makes $each method skip private properties (9d36bdd)
9+
10+
111
# 0.12.0 (2014-01-24)
212

313
## Features

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-restmod",
3-
"version": "0.12.2",
3+
"version": "0.13.0",
44
"authors": [
55
"Ignacio Baixas <[email protected]>"
66
],

dist/angular-restmod.js

Lines changed: 69 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* API Bound Models for AngularJS
3-
* @version v0.12.2 - 2014-02-27
3+
* @version v0.13.0 - 2014-03-14
44
* @link https://github.com/angular-platanus/restmod
55
* @author Ignacio Baixas <[email protected]>
66
* @license MIT License, http://www.opensource.org/licenses/MIT
@@ -95,39 +95,7 @@ var Utils = {
9595
// make this available as a restmod constant
9696
angular.module('plRestmod').constant('Utils', Utils);
9797

98-
/**
99-
* @class SyncMask
100-
* @memberOf constants
101-
*
102-
* @description The object property synchronization mask.
103-
*/
104-
var SyncMask = {
105-
NONE: 0x00,
106-
ALL: 0xFFFF,
107-
SYSTEM_ALL: 0x1FFFF,
108-
109-
SYSTEM: 0x10000,
110-
111-
DECODE_CREATE: 0x0001,
112-
DECODE_UPDATE: 0x0002,
113-
DECODE_USER: 0x0004,
114-
DECODE_SAVE: 0x0003,
115-
116-
ENCODE_CREATE: 0x0100,
117-
ENCODE_UPDATE: 0x0200,
118-
ENCODE_USER: 0x0400,
119-
ENCODE_SAVE: 0x0300,
120-
121-
// Compound masks
122-
DECODE: 0x00FF,
123-
ENCODE: 0xFF00,
124-
CREATE: 0x0101,
125-
UPDATE: 0x0202,
126-
USER: 0x0404,
127-
SAVE: 0x0303
128-
};
129-
130-
// Cache some angular stuff
98+
// Preload some angular stuff
13199
var bind = angular.bind,
132100
forEach = angular.forEach,
133101
extend = angular.extend,
@@ -136,6 +104,13 @@ var bind = angular.bind,
136104
isFunction = angular.isFunction,
137105
arraySlice = Array.prototype.slice;
138106

107+
// Constants
108+
var CREATE_MASK = 'C',
109+
UPDATE_MASK = 'U',
110+
READ_MASK = 'R',
111+
WRITE_MASK = 'CU',
112+
FULL_MASK = 'CRU';
113+
139114
/**
140115
* @class $restmodProvider
141116
* @memberOf providers
@@ -193,15 +168,7 @@ angular.module('plRestmod').provider('$restmod', function() {
193168
*/
194169
model: function(_baseUrl/* , _mix */) {
195170

196-
var masks = {
197-
$type: SyncMask.SYSTEM_ALL,
198-
$scope: SyncMask.SYSTEM_ALL,
199-
$promise: SyncMask.SYSTEM_ALL,
200-
$pending: SyncMask.SYSTEM_ALL,
201-
$response: SyncMask.SYSTEM_ALL,
202-
$status: SyncMask.SYSTEM_ALL,
203-
$cb: SyncMask.SYSTEM_ALL
204-
},
171+
var masks = {},
205172
urlPrefix = null,
206173
primaryKey = 'id',
207174
defaults = [],
@@ -317,32 +284,34 @@ angular.module('plRestmod').provider('$restmod', function() {
317284
// recursive transformation function, used by $decode and $encode.
318285
function transform(_data, _ctx, _prefix, _mask, _decode, _into) {
319286

320-
var key, decodedName, encodedName, fullName, filter, value, result = _into || {};
287+
var key, decodedName, encodedName, fullName, mask, filter, value, result = _into || {};
321288

322289
for(key in _data) {
323-
if(_data.hasOwnProperty(key) && !(!_decode && key[0] === '$' && key[1] === '$')) {
290+
if(_data.hasOwnProperty(key) && key[0] !== '$') {
324291

325292
decodedName = (_decode && nameDecoder) ? nameDecoder(key) : key;
326293
fullName = _prefix + decodedName;
327294

328-
// check if property is masked for this operation
329-
if(!((masks[fullName] || 0) & _mask)) {
330-
331-
value = _data[key];
332-
filter = _decode ? decoders[fullName] : encoders[fullName];
295+
// skip property if masked for this operation
296+
mask = masks[fullName];
297+
if(mask && mask.indexOf(_mask) !== -1) {
298+
continue;
299+
}
333300

334-
if(filter) {
335-
value = filter.call(_ctx, value);
336-
if(value === undefined) continue; // ignore value if filter returns undefined
337-
} else if(typeof value === 'object' && value &&
338-
(_decode || typeof value.toJSON !== 'function')) {
339-
// IDEA: make extended decoding/encoding optional, could be a little taxxing for some apps
340-
value = transformExtended(value, _ctx, fullName, _mask, _decode);
341-
}
301+
value = _data[key];
302+
filter = _decode ? decoders[fullName] : encoders[fullName];
342303

343-
encodedName = (!_decode && nameEncoder) ? nameEncoder(decodedName) : decodedName;
344-
result[encodedName] = value;
304+
if(filter) {
305+
value = filter.call(_ctx, value);
306+
if(value === undefined) continue; // ignore value if filter returns undefined
307+
} else if(typeof value === 'object' && value &&
308+
(_decode || typeof value.toJSON !== 'function')) {
309+
// IDEA: make extended decoding/encoding optional, could be a little taxing for some apps
310+
value = transformExtended(value, _ctx, fullName, _mask, _decode);
345311
}
312+
313+
encodedName = (!_decode && nameEncoder) ? nameEncoder(decodedName) : decodedName;
314+
result[encodedName] = value;
346315
}
347316
}
348317

@@ -494,7 +463,11 @@ angular.module('plRestmod').provider('$restmod', function() {
494463

495464
// sets an attribute mask at runtime
496465
Model.$$setMask = function(_attr, _mask) {
497-
masks[_attr] = _mask;
466+
if(!_mask) {
467+
delete masks[_attr];
468+
} else {
469+
masks[_attr] = _mask === true ? FULL_MASK : _mask;
470+
}
498471
};
499472

500473
// registers a new global hook
@@ -587,21 +560,15 @@ angular.module('plRestmod').provider('$restmod', function() {
587560
/**
588561
* @memberof Model#
589562
*
590-
* @description Iterates over the object properties
563+
* @description Iterates over the object non-private properties
591564
*
592565
* @param {function} _fun Function to call for each
593-
* @param {SyncMask} _mask Mask used to filter the returned properties, defaults to SyncMask.SYSTEM
594566
* @return {Model} self
595567
*/
596-
$each: function(_fun, _mask, _ctx) {
597-
if(_mask === undefined) _mask = SyncMask.SYSTEM;
598-
568+
$each: function(_fun, _ctx) {
599569
for(var key in this) {
600-
if(this.hasOwnProperty(key)) {
601-
// Only iterate at base level for now
602-
if(!((masks[key] || 0) & _mask)) {
603-
_fun.call(_ctx || this[key], this[key], key);
604-
}
570+
if(this.hasOwnProperty(key) && key[0] !== '$') {
571+
_fun.call(_ctx || this[key], this[key], key);
605572
}
606573
}
607574

@@ -703,11 +670,10 @@ angular.module('plRestmod').provider('$restmod', function() {
703670
* @description Feed raw data to this instance.
704671
*
705672
* @param {object} _raw Raw data to be fed
706-
* @param {string} _mask Action mask
707673
* @return {Model} this
708674
*/
709675
$decode: function(_raw, _mask) {
710-
transform(_raw, this, '', _mask || SyncMask.DECODE_USER, true, this);
676+
transform(_raw, this, '', _mask || READ_MASK, true, this);
711677
if(!this.$pk) this.$pk = Model.$inferKey(this); // TODO: improve this, warn if key changes
712678
callback('after-feed', this, _raw);
713679
return this;
@@ -722,7 +688,7 @@ angular.module('plRestmod').provider('$restmod', function() {
722688
* @return {Model} this
723689
*/
724690
$encode: function(_mask) {
725-
var raw = transform(this, this, '', _mask || SyncMask.ENCODE_USER, false);
691+
var raw = transform(this, this, '', _mask || CREATE_MASK, false);
726692
callback('before-render', this, raw);
727693
return raw;
728694
},
@@ -772,12 +738,12 @@ angular.module('plRestmod').provider('$restmod', function() {
772738

773739
if(url) {
774740
// If bound, update
775-
request = { method: 'PUT', url: url, data: this.$encode(SyncMask.ENCODE_UPDATE) };
741+
request = { method: 'PUT', url: url, data: this.$encode(CREATE_MASK) };
776742
callback('before-update', this, request);
777743
callback('before-save', this, request);
778744
return this.$send(request, function(_response) {
779745
var data = _response.data;
780-
if (data && !isArray(data)) this.$decode(data, SyncMask.DECODE_UPDATE);
746+
if (data && !isArray(data)) this.$decode(data);
781747
callback('after-update', this, _response);
782748
callback('after-save', this, _response);
783749
}, function(_response) {
@@ -788,12 +754,12 @@ angular.module('plRestmod').provider('$restmod', function() {
788754
// If not bound create.
789755
url = this.$scope.$createUrlFor ? this.$scope.$createUrlFor(this.$pk) : (this.$scope.$url && this.$scope.$url());
790756
if(!url) throw new Error('Create is not supported by this resource');
791-
request = { method: 'POST', url: url, data: this.$encode(SyncMask.ENCODE_CREATE) };
757+
request = { method: 'POST', url: url, data: this.$encode(UPDATE_MASK) };
792758
callback('before-save', this, request);
793759
callback('before-create', this, request);
794760
return this.$send(request, function(_response) {
795761
var data = _response.data;
796-
if (data && !isArray(data)) this.$decode(data, SyncMask.DECODE_CREATE);
762+
if (data && !isArray(data)) this.$decode(data);
797763
callback('after-create', this, _response);
798764
callback('after-save', this, _response);
799765
}, function(_response) {
@@ -1508,23 +1474,28 @@ angular.module('plRestmod').provider('$restmod', function() {
15081474
*
15091475
* @description Sets an attribute mask.
15101476
*
1477+
* An attribute mask prevents the attribute to be loaded from or sent to the server on certain operations.
1478+
*
1479+
* The attribute mask is a string composed by:
1480+
* * C: To prevent attribute from being sent on create
1481+
* * R: To prevent attribute from being loaded from server
1482+
* * U: To prevent attribute from being sent on update
1483+
*
1484+
* For example, the following will prevent an attribute to be send on create or update:
1485+
*
1486+
* ```javascript
1487+
* builder.attrMask('readOnly', 'CU');
1488+
* ```
1489+
*
1490+
* If a true boolean value is passed as mask, then 'CRU' will be used
1491+
* If a false boolean valus is passed as mask, then mask will be removed
1492+
*
15111493
* @param {string} _attr Attribute name
1512-
* @param {boolean|integer} _mask Ignore mask or true to use SyncMask.ALL
1513-
* @param {boolean} _reset If set to true, old mask is reset.
1494+
* @param {boolean|string} _mask Attribute mask
15141495
* @return {ModelBuilder} self
15151496
*/
1516-
attrMask: function(_attr, _mask, _reset) {
1517-
1518-
if(_mask === true) {
1519-
masks[_attr] = SyncMask.ALL;
1520-
} else if(_mask === false) {
1521-
delete masks[_attr];
1522-
} else if(_reset) {
1523-
masks[_attr] = _mask;
1524-
} else {
1525-
masks[_attr] |= _mask;
1526-
}
1527-
1497+
attrMask: function(_attr, _mask) {
1498+
Model.$$setMask(_attr, _mask);
15281499
return this;
15291500
},
15301501

@@ -1617,7 +1588,7 @@ angular.module('plRestmod').provider('$restmod', function() {
16171588
_model = $injector.get(_model);
16181589

16191590
if(_inverseOf) {
1620-
_model.$$setMask(_inverseOf, SyncMask.ENCODE);
1591+
_model.$$setMask(_inverseOf, WRITE_MASK);
16211592
}
16221593
}
16231594

@@ -1642,7 +1613,7 @@ angular.module('plRestmod').provider('$restmod', function() {
16421613
// simple support for inline data, TODO: maybe deprecate this.
16431614
}).attrDecoder(_source || _url || _attr, function(_raw) {
16441615
this[_attr].$reset().$feed(_raw);
1645-
}).attrMask(_attr, SyncMask.ENCODE);
1616+
}).attrMask(_attr, WRITE_MASK);
16461617
},
16471618

16481619
/**
@@ -1666,7 +1637,7 @@ angular.module('plRestmod').provider('$restmod', function() {
16661637
_model = $injector.get(_model);
16671638

16681639
if(_inverseOf) {
1669-
_model.$$setMask(_inverseOf, SyncMask.ENCODE);
1640+
_model.$$setMask(_inverseOf, WRITE_MASK);
16701641
}
16711642
}
16721643

@@ -1685,7 +1656,7 @@ angular.module('plRestmod').provider('$restmod', function() {
16851656
.attrDecoder(_source || _url || _attr, function(_raw) {
16861657
this[_attr].$decode(_raw);
16871658
})
1688-
.attrMask(_attr, SyncMask.ENCODE);
1659+
.attrMask(_attr, WRITE_MASK);
16891660
},
16901661

16911662
/**
@@ -1707,7 +1678,7 @@ angular.module('plRestmod').provider('$restmod', function() {
17071678
var watch = _inline ? (_source || _attr) : (_key || (_attr + 'Id'));
17081679
this
17091680
.attrDefault(_attr, null)
1710-
.attrMask(_attr, SyncMask.ENCODE)
1681+
.attrMask(_attr, WRITE_MASK)
17111682
.attrDecoder(watch , function(_raw) {
17121683

17131684
// load model
@@ -1892,8 +1863,6 @@ angular.module('plRestmod').provider('$restmod', function() {
18921863
}])
18931864
.factory('mixin', ['$restmod', function($restmod) {
18941865
return $restmod.mixin;
1895-
}])
1896-
// make SyncMask available as constant
1897-
.constant('SyncMask', SyncMask);
1866+
}]);
18981867

18991868
})(angular);

0 commit comments

Comments
 (0)