Skip to content

Commit

Permalink
0.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
phillipskevin committed Dec 1, 2017
1 parent c517752 commit d46dc68
Show file tree
Hide file tree
Showing 3 changed files with 914 additions and 0 deletions.
264 changes: 264 additions & 0 deletions dist/amd/can-stache-key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
/*can-stache-key@0.1.2#can-stache-key*/
define([
'require',
'exports',
'module',
'can-observation',
'can-log/dev',
'can-util/js/each',
'can-symbol',
'can-reflect',
'can-util/js/is-promise-like',
'can-reflect-promise'
], function (require, exports, module) {
var Observation = require('can-observation');
var dev = require('can-log/dev');
var each = require('can-util/js/each');
var canSymbol = require('can-symbol');
var canReflect = require('can-reflect');
var isPromiseLike = require('can-util/js/is-promise-like');
var canReflectPromise = require('can-reflect-promise');
var getValueSymbol = canSymbol.for('can.getValue');
var setValueSymbol = canSymbol.for('can.setValue');
var isValueLikeSymbol = canSymbol.for('can.isValueLike');
var observeReader;
var isAt = function (index, reads) {
var prevRead = reads[index - 1];
return prevRead && prevRead.at;
};
var readValue = function (value, index, reads, options, state, prev) {
var usedValueReader;
do {
usedValueReader = false;
for (var i = 0, len = observeReader.valueReaders.length; i < len; i++) {
if (observeReader.valueReaders[i].test(value, index, reads, options)) {
value = observeReader.valueReaders[i].read(value, index, reads, options, state, prev);
}
}
} while (usedValueReader);
return value;
};
var specialRead = {
index: true,
key: true,
event: true,
element: true,
viewModel: true
};
var checkForObservableAndNotify = function (options, state, getObserves, value, index) {
if (options.foundObservable && !state.foundObservable) {
if (Observation.trapsCount()) {
Observation.addAll(getObserves());
options.foundObservable(value, index);
state.foundObservable = true;
}
}
};
observeReader = {
read: function (parent, reads, options) {
options = options || {};
var state = { foundObservable: false };
var getObserves;
if (options.foundObservable) {
getObserves = Observation.trap();
}
var cur = readValue(parent, 0, reads, options, state), type, prev, readLength = reads.length, i = 0, last;
checkForObservableAndNotify(options, state, getObserves, parent, 0);
while (i < readLength) {
prev = cur;
for (var r = 0, readersLength = observeReader.propertyReaders.length; r < readersLength; r++) {
var reader = observeReader.propertyReaders[r];
if (reader.test(cur)) {
cur = reader.read(cur, reads[i], i, options, state);
break;
}
}
checkForObservableAndNotify(options, state, getObserves, prev, i);
last = cur;
i = i + 1;
cur = readValue(cur, i, reads, options, state, prev);
checkForObservableAndNotify(options, state, getObserves, prev, i - 1);
type = typeof cur;
if (i < reads.length && (cur === null || cur === undefined)) {
if (options.earlyExit) {
options.earlyExit(prev, i - 1, cur);
}
return {
value: undefined,
parent: prev
};
}
}
if (cur === undefined) {
if (options.earlyExit) {
options.earlyExit(prev, i - 1);
}
}
return {
value: cur,
parent: prev
};
},
get: function (parent, reads, options) {
return observeReader.read(parent, observeReader.reads(reads), options || {}).value;
},
valueReadersMap: {},
valueReaders: [
{
name: 'function',
test: function (value) {
return value && canReflect.isFunctionLike(value) && !canReflect.isConstructorLike(value);
},
read: function (value, i, reads, options, state, prev) {
if (isAt(i, reads)) {
return i === reads.length ? value.bind(prev) : value;
}
if (options.callMethodsOnObservables && canReflect.isObservableLike(prev) && canReflect.isMapLike(prev)) {
return value.apply(prev, options.args || []);
} else if (options.isArgument && i === reads.length) {
if (options.proxyMethods === false) {
return value;
}
return value.bind(prev);
}
return value.apply(prev, options.args || []);
}
},
{
name: 'isValueLike',
test: function (value, i, reads, options) {
return value && value[getValueSymbol] && value[isValueLikeSymbol] !== false && (options.foundAt || !isAt(i, reads));
},
read: function (value, i, reads, options) {
if (options.readCompute === false && i === reads.length) {
return value;
}
return canReflect.getValue(value);
},
write: function (base, newVal) {
if (base[setValueSymbol]) {
base[setValueSymbol](newVal);
} else if (base.set) {
base.set(newVal);
} else {
base(newVal);
}
}
}
],
propertyReadersMap: {},
propertyReaders: [
{
name: 'map',
test: function (value) {
if (isPromiseLike(value) || typeof value === 'object' && value && typeof value.then === 'function') {
canReflectPromise(value);
}
return canReflect.isObservableLike(value) && canReflect.isMapLike(value);
},
read: function (value, prop) {
var res = canReflect.getKeyValue(value, prop.key);
if (res !== undefined) {
return res;
} else {
return value[prop.key];
}
},
write: canReflect.setKeyValue
},
{
name: 'object',
test: function () {
return true;
},
read: function (value, prop, i, options) {
if (value == null) {
return undefined;
} else {
if (typeof value === 'object') {
if (prop.key in value) {
return value[prop.key];
} else if (prop.at && specialRead[prop.key] && '@' + prop.key in value) {
options.foundAt = true;
return value['@' + prop.key];
}
} else {
return value[prop.key];
}
}
},
write: function (base, prop, newVal) {
base[prop] = newVal;
}
}
],
reads: function (keyArg) {
var key = '' + keyArg;
var keys = [];
var last = 0;
var at = false;
if (key.charAt(0) === '@') {
last = 1;
at = true;
}
var keyToAdd = '';
for (var i = last; i < key.length; i++) {
var character = key.charAt(i);
if (character === '.' || character === '@') {
if (key.charAt(i - 1) !== '\\') {
keys.push({
key: keyToAdd,
at: at
});
at = character === '@';
keyToAdd = '';
} else {
keyToAdd = keyToAdd.substr(0, keyToAdd.length - 1) + '.';
}
} else {
keyToAdd += character;
}
}
keys.push({
key: keyToAdd,
at: at
});
return keys;
},
write: function (parent, key, value, options) {
var keys = typeof key === 'string' ? observeReader.reads(key) : key;
var last;
options = options || {};
if (keys.length > 1) {
last = keys.pop();
parent = observeReader.read(parent, keys, options).value;
keys.push(last);
} else {
last = keys[0];
}
if (observeReader.valueReadersMap.isValueLike.test(parent[last.key], keys.length - 1, keys, options)) {
observeReader.valueReadersMap.isValueLike.write(parent[last.key], value, options);
} else {
if (observeReader.valueReadersMap.isValueLike.test(parent, keys.length - 1, keys, options)) {
parent = parent[getValueSymbol]();
}
if (observeReader.propertyReadersMap.map.test(parent)) {
observeReader.propertyReadersMap.map.write(parent, last.key, value, options);
} else if (observeReader.propertyReadersMap.object.test(parent)) {
observeReader.propertyReadersMap.object.write(parent, last.key, value, options);
if (options.observation) {
options.observation.update();
}
}
}
}
};
each(observeReader.propertyReaders, function (reader) {
observeReader.propertyReadersMap[reader.name] = reader;
});
each(observeReader.valueReaders, function (reader) {
observeReader.valueReadersMap[reader.name] = reader;
});
observeReader.set = observeReader.write;
module.exports = observeReader;
});
Loading

0 comments on commit d46dc68

Please sign in to comment.