mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
Make polymer-expressions/path-parser a simple CommonJS module.
The weird module.exports code broke the webpack parser.
This commit is contained in:
@ -7,403 +7,387 @@
|
|||||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function (global) {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function detectEval() {
|
function detectEval() {
|
||||||
// Don't test for eval if we're running in a Chrome App environment.
|
// Don't test for eval if we're running in a Chrome App environment.
|
||||||
// We check for APIs set that only exist in a Chrome App context.
|
// We check for APIs set that only exist in a Chrome App context.
|
||||||
if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) {
|
if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Firefox OS Apps do not allow eval. This feature detection is very hacky
|
|
||||||
// but even if some other platform adds support for this function this code
|
|
||||||
// will continue to work.
|
|
||||||
if (typeof navigator != 'undefined' && navigator.getDeviceStorage) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var f = new Function('', 'return true;');
|
|
||||||
return f();
|
|
||||||
} catch (ex) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasEval = detectEval();
|
// Firefox OS Apps do not allow eval. This feature detection is very hacky
|
||||||
|
// but even if some other platform adds support for this function this code
|
||||||
function isIndex(s) {
|
// will continue to work.
|
||||||
return +s === s >>> 0 && s !== '';
|
if (typeof navigator != 'undefined' && navigator.getDeviceStorage) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toNumber(s) {
|
try {
|
||||||
return +s;
|
var f = new Function('', 'return true;');
|
||||||
|
return f();
|
||||||
|
} catch (ex) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isObject(obj) {
|
var hasEval = detectEval();
|
||||||
return obj === Object(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
var numberIsNaN = global.Number.isNaN || function (value) {
|
function isIndex(s) {
|
||||||
return typeof value === 'number' && global.isNaN(value);
|
return +s === s >>> 0 && s !== '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function areSameValue(left, right) {
|
function toNumber(s) {
|
||||||
if (left === right)
|
return +s;
|
||||||
return left !== 0 || 1 / left === 1 / right;
|
}
|
||||||
if (numberIsNaN(left) && numberIsNaN(right))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return left !== left && right !== right;
|
function isObject(obj) {
|
||||||
}
|
return obj === Object(obj);
|
||||||
|
}
|
||||||
|
|
||||||
var createObject = ('__proto__' in {}) ?
|
var numberIsNaN = Number.isNaN || function (value) {
|
||||||
function (obj) { return obj; } :
|
return typeof value === 'number' && isNaN(value);
|
||||||
function (obj) {
|
}
|
||||||
var proto = obj.__proto__;
|
|
||||||
if (!proto)
|
|
||||||
return obj;
|
|
||||||
var newObject = Object.create(proto);
|
|
||||||
Object.getOwnPropertyNames(obj).forEach(function (name) {
|
|
||||||
Object.defineProperty(newObject, name,
|
|
||||||
Object.getOwnPropertyDescriptor(obj, name));
|
|
||||||
});
|
|
||||||
return newObject;
|
|
||||||
};
|
|
||||||
|
|
||||||
var identStart = '[\$_a-zA-Z]';
|
function areSameValue(left, right) {
|
||||||
var identPart = '[\$_a-zA-Z0-9]';
|
if (left === right)
|
||||||
var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
|
return left !== 0 || 1 / left === 1 / right;
|
||||||
|
if (numberIsNaN(left) && numberIsNaN(right))
|
||||||
|
return true;
|
||||||
|
|
||||||
function getPathCharType(char) {
|
return left !== left && right !== right;
|
||||||
if (char === undefined)
|
}
|
||||||
return 'eof';
|
|
||||||
|
|
||||||
var code = char.charCodeAt(0);
|
var createObject = ('__proto__' in {}) ?
|
||||||
|
function (obj) { return obj; } :
|
||||||
|
function (obj) {
|
||||||
|
var proto = obj.__proto__;
|
||||||
|
if (!proto)
|
||||||
|
return obj;
|
||||||
|
var newObject = Object.create(proto);
|
||||||
|
Object.getOwnPropertyNames(obj).forEach(function (name) {
|
||||||
|
Object.defineProperty(newObject, name,
|
||||||
|
Object.getOwnPropertyDescriptor(obj, name));
|
||||||
|
});
|
||||||
|
return newObject;
|
||||||
|
};
|
||||||
|
|
||||||
switch (code) {
|
var identStart = '[\$_a-zA-Z]';
|
||||||
case 0x5B: // [
|
var identPart = '[\$_a-zA-Z0-9]';
|
||||||
case 0x5D: // ]
|
var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
|
||||||
case 0x2E: // .
|
|
||||||
case 0x22: // "
|
|
||||||
case 0x27: // '
|
|
||||||
case 0x30: // 0
|
|
||||||
return char;
|
|
||||||
|
|
||||||
case 0x5F: // _
|
function getPathCharType(char) {
|
||||||
case 0x24: // $
|
if (char === undefined)
|
||||||
return 'ident';
|
return 'eof';
|
||||||
|
|
||||||
case 0x20: // Space
|
var code = char.charCodeAt(0);
|
||||||
case 0x09: // Tab
|
|
||||||
case 0x0A: // Newline
|
|
||||||
case 0x0D: // Return
|
|
||||||
case 0xA0: // No-break space
|
|
||||||
case 0xFEFF: // Byte Order Mark
|
|
||||||
case 0x2028: // Line Separator
|
|
||||||
case 0x2029: // Paragraph Separator
|
|
||||||
return 'ws';
|
|
||||||
}
|
|
||||||
|
|
||||||
// a-z, A-Z
|
switch (code) {
|
||||||
if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
|
case 0x5B: // [
|
||||||
|
case 0x5D: // ]
|
||||||
|
case 0x2E: // .
|
||||||
|
case 0x22: // "
|
||||||
|
case 0x27: // '
|
||||||
|
case 0x30: // 0
|
||||||
|
return char;
|
||||||
|
|
||||||
|
case 0x5F: // _
|
||||||
|
case 0x24: // $
|
||||||
return 'ident';
|
return 'ident';
|
||||||
|
|
||||||
// 1-9
|
case 0x20: // Space
|
||||||
if (0x31 <= code && code <= 0x39)
|
case 0x09: // Tab
|
||||||
return 'number';
|
case 0x0A: // Newline
|
||||||
|
case 0x0D: // Return
|
||||||
return 'else';
|
case 0xA0: // No-break space
|
||||||
|
case 0xFEFF: // Byte Order Mark
|
||||||
|
case 0x2028: // Line Separator
|
||||||
|
case 0x2029: // Paragraph Separator
|
||||||
|
return 'ws';
|
||||||
}
|
}
|
||||||
|
|
||||||
var pathStateMachine = {
|
// a-z, A-Z
|
||||||
'beforePath': {
|
if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
|
||||||
'ws': ['beforePath'],
|
return 'ident';
|
||||||
'ident': ['inIdent', 'append'],
|
|
||||||
'[': ['beforeElement'],
|
|
||||||
'eof': ['afterPath']
|
|
||||||
},
|
|
||||||
|
|
||||||
'inPath': {
|
// 1-9
|
||||||
'ws': ['inPath'],
|
if (0x31 <= code && code <= 0x39)
|
||||||
'.': ['beforeIdent'],
|
return 'number';
|
||||||
'[': ['beforeElement'],
|
|
||||||
'eof': ['afterPath']
|
|
||||||
},
|
|
||||||
|
|
||||||
'beforeIdent': {
|
return 'else';
|
||||||
'ws': ['beforeIdent'],
|
}
|
||||||
'ident': ['inIdent', 'append']
|
|
||||||
},
|
|
||||||
|
|
||||||
'inIdent': {
|
var pathStateMachine = {
|
||||||
'ident': ['inIdent', 'append'],
|
'beforePath': {
|
||||||
'0': ['inIdent', 'append'],
|
'ws': ['beforePath'],
|
||||||
'number': ['inIdent', 'append'],
|
'ident': ['inIdent', 'append'],
|
||||||
'ws': ['inPath', 'push'],
|
'[': ['beforeElement'],
|
||||||
'.': ['beforeIdent', 'push'],
|
'eof': ['afterPath']
|
||||||
'[': ['beforeElement', 'push'],
|
},
|
||||||
'eof': ['afterPath', 'push']
|
|
||||||
},
|
|
||||||
|
|
||||||
'beforeElement': {
|
'inPath': {
|
||||||
'ws': ['beforeElement'],
|
'ws': ['inPath'],
|
||||||
'0': ['afterZero', 'append'],
|
'.': ['beforeIdent'],
|
||||||
'number': ['inIndex', 'append'],
|
'[': ['beforeElement'],
|
||||||
"'": ['inSingleQuote', 'append', ''],
|
'eof': ['afterPath']
|
||||||
'"': ['inDoubleQuote', 'append', '']
|
},
|
||||||
},
|
|
||||||
|
|
||||||
'afterZero': {
|
'beforeIdent': {
|
||||||
'ws': ['afterElement', 'push'],
|
'ws': ['beforeIdent'],
|
||||||
']': ['inPath', 'push']
|
'ident': ['inIdent', 'append']
|
||||||
},
|
},
|
||||||
|
|
||||||
'inIndex': {
|
'inIdent': {
|
||||||
'0': ['inIndex', 'append'],
|
'ident': ['inIdent', 'append'],
|
||||||
'number': ['inIndex', 'append'],
|
'0': ['inIdent', 'append'],
|
||||||
'ws': ['afterElement'],
|
'number': ['inIdent', 'append'],
|
||||||
']': ['inPath', 'push']
|
'ws': ['inPath', 'push'],
|
||||||
},
|
'.': ['beforeIdent', 'push'],
|
||||||
|
'[': ['beforeElement', 'push'],
|
||||||
|
'eof': ['afterPath', 'push']
|
||||||
|
},
|
||||||
|
|
||||||
'inSingleQuote': {
|
'beforeElement': {
|
||||||
"'": ['afterElement'],
|
'ws': ['beforeElement'],
|
||||||
'eof': ['error'],
|
'0': ['afterZero', 'append'],
|
||||||
'else': ['inSingleQuote', 'append']
|
'number': ['inIndex', 'append'],
|
||||||
},
|
"'": ['inSingleQuote', 'append', ''],
|
||||||
|
'"': ['inDoubleQuote', 'append', '']
|
||||||
|
},
|
||||||
|
|
||||||
'inDoubleQuote': {
|
'afterZero': {
|
||||||
'"': ['afterElement'],
|
'ws': ['afterElement', 'push'],
|
||||||
'eof': ['error'],
|
']': ['inPath', 'push']
|
||||||
'else': ['inDoubleQuote', 'append']
|
},
|
||||||
},
|
|
||||||
|
|
||||||
'afterElement': {
|
'inIndex': {
|
||||||
'ws': ['afterElement'],
|
'0': ['inIndex', 'append'],
|
||||||
']': ['inPath', 'push']
|
'number': ['inIndex', 'append'],
|
||||||
}
|
'ws': ['afterElement'],
|
||||||
|
']': ['inPath', 'push']
|
||||||
|
},
|
||||||
|
|
||||||
|
'inSingleQuote': {
|
||||||
|
"'": ['afterElement'],
|
||||||
|
'eof': ['error'],
|
||||||
|
'else': ['inSingleQuote', 'append']
|
||||||
|
},
|
||||||
|
|
||||||
|
'inDoubleQuote': {
|
||||||
|
'"': ['afterElement'],
|
||||||
|
'eof': ['error'],
|
||||||
|
'else': ['inDoubleQuote', 'append']
|
||||||
|
},
|
||||||
|
|
||||||
|
'afterElement': {
|
||||||
|
'ws': ['afterElement'],
|
||||||
|
']': ['inPath', 'push']
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function noop() { }
|
function noop() { }
|
||||||
|
|
||||||
function parsePath(path) {
|
function parsePath(path) {
|
||||||
var keys = [];
|
var keys = [];
|
||||||
var index = -1;
|
var index = -1;
|
||||||
var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
|
var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
|
||||||
|
|
||||||
var actions = {
|
var actions = {
|
||||||
push: function () {
|
push: function () {
|
||||||
if (key === undefined)
|
if (key === undefined)
|
||||||
return;
|
|
||||||
|
|
||||||
keys.push(key);
|
|
||||||
key = undefined;
|
|
||||||
},
|
|
||||||
|
|
||||||
append: function () {
|
|
||||||
if (key === undefined)
|
|
||||||
key = newChar
|
|
||||||
else
|
|
||||||
key += newChar;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function maybeUnescapeQuote() {
|
|
||||||
if (index >= path.length)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var nextChar = path[index + 1];
|
keys.push(key);
|
||||||
if ((mode == 'inSingleQuote' && nextChar == "'") ||
|
key = undefined;
|
||||||
(mode == 'inDoubleQuote' && nextChar == '"')) {
|
},
|
||||||
index++;
|
|
||||||
newChar = nextChar;
|
|
||||||
actions.append();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (mode) {
|
append: function () {
|
||||||
|
if (key === undefined)
|
||||||
|
key = newChar
|
||||||
|
else
|
||||||
|
key += newChar;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function maybeUnescapeQuote() {
|
||||||
|
if (index >= path.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var nextChar = path[index + 1];
|
||||||
|
if ((mode == 'inSingleQuote' && nextChar == "'") ||
|
||||||
|
(mode == 'inDoubleQuote' && nextChar == '"')) {
|
||||||
index++;
|
index++;
|
||||||
c = path[index];
|
newChar = nextChar;
|
||||||
|
actions.append();
|
||||||
if (c == '\\' && maybeUnescapeQuote(mode))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
type = getPathCharType(c);
|
|
||||||
typeMap = pathStateMachine[mode];
|
|
||||||
transition = typeMap[type] || typeMap['else'] || 'error';
|
|
||||||
|
|
||||||
if (transition == 'error')
|
|
||||||
return; // parse error;
|
|
||||||
|
|
||||||
mode = transition[0];
|
|
||||||
action = actions[transition[1]] || noop;
|
|
||||||
newChar = transition[2] === undefined ? c : transition[2];
|
|
||||||
action();
|
|
||||||
|
|
||||||
if (mode === 'afterPath') {
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return; // parse error
|
|
||||||
}
|
|
||||||
|
|
||||||
function isIdent(s) {
|
|
||||||
return identRegExp.test(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
var constructorIsPrivate = {};
|
|
||||||
|
|
||||||
function Path(parts, privateToken) {
|
|
||||||
if (privateToken !== constructorIsPrivate)
|
|
||||||
throw Error('Use Path.get to retrieve path objects');
|
|
||||||
|
|
||||||
for (var i = 0; i < parts.length; i++) {
|
|
||||||
this.push(String(parts[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasEval && this.length) {
|
|
||||||
this.getValueFrom = this.compiledGetValueFromFn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(rafaelw): Make simple LRU cache
|
|
||||||
var pathCache = {};
|
|
||||||
|
|
||||||
function getPath(pathString) {
|
|
||||||
if (pathString instanceof Path)
|
|
||||||
return pathString;
|
|
||||||
|
|
||||||
if (pathString == null || pathString.length == 0)
|
|
||||||
pathString = '';
|
|
||||||
|
|
||||||
if (typeof pathString != 'string') {
|
|
||||||
if (isIndex(pathString.length)) {
|
|
||||||
// Constructed with array-like (pre-parsed) keys
|
|
||||||
return new Path(pathString, constructorIsPrivate);
|
|
||||||
}
|
|
||||||
|
|
||||||
pathString = String(pathString);
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = pathCache[pathString];
|
|
||||||
if (path)
|
|
||||||
return path;
|
|
||||||
|
|
||||||
var parts = parsePath(pathString);
|
|
||||||
if (!parts)
|
|
||||||
return invalidPath;
|
|
||||||
|
|
||||||
var path = new Path(parts, constructorIsPrivate);
|
|
||||||
pathCache[pathString] = path;
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Path.get = getPath;
|
|
||||||
|
|
||||||
function formatAccessor(key) {
|
|
||||||
if (isIndex(key)) {
|
|
||||||
return '[' + key + ']';
|
|
||||||
} else {
|
|
||||||
return '["' + key.replace(/"/g, '\\"') + '"]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Path.prototype = createObject({
|
|
||||||
__proto__: [],
|
|
||||||
valid: true,
|
|
||||||
|
|
||||||
toString: function () {
|
|
||||||
var pathString = '';
|
|
||||||
for (var i = 0; i < this.length; i++) {
|
|
||||||
var key = this[i];
|
|
||||||
if (isIdent(key)) {
|
|
||||||
pathString += i ? '.' + key : key;
|
|
||||||
} else {
|
|
||||||
pathString += formatAccessor(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pathString;
|
|
||||||
},
|
|
||||||
|
|
||||||
getValueFrom: function (obj, directObserver) {
|
|
||||||
for (var i = 0; i < this.length; i++) {
|
|
||||||
if (obj == null)
|
|
||||||
return;
|
|
||||||
obj = obj[this[i]];
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
|
|
||||||
iterateObjects: function (obj, observe) {
|
|
||||||
for (var i = 0; i < this.length; i++) {
|
|
||||||
if (i)
|
|
||||||
obj = obj[this[i - 1]];
|
|
||||||
if (!isObject(obj))
|
|
||||||
return;
|
|
||||||
observe(obj, this[i]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
compiledGetValueFromFn: function () {
|
|
||||||
var str = '';
|
|
||||||
var pathString = 'obj';
|
|
||||||
str += 'if (obj != null';
|
|
||||||
var i = 0;
|
|
||||||
var key;
|
|
||||||
for (; i < (this.length - 1) ; i++) {
|
|
||||||
key = this[i];
|
|
||||||
pathString += isIdent(key) ? '.' + key : formatAccessor(key);
|
|
||||||
str += ' &&\n ' + pathString + ' != null';
|
|
||||||
}
|
|
||||||
str += ')\n';
|
|
||||||
|
|
||||||
var key = this[i];
|
|
||||||
pathString += isIdent(key) ? '.' + key : formatAccessor(key);
|
|
||||||
|
|
||||||
str += ' return ' + pathString + ';\nelse\n return undefined;';
|
|
||||||
return new Function('obj', str);
|
|
||||||
},
|
|
||||||
|
|
||||||
setValueFrom: function (obj, value) {
|
|
||||||
if (!this.length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (var i = 0; i < this.length - 1; i++) {
|
|
||||||
if (!isObject(obj))
|
|
||||||
return false;
|
|
||||||
obj = obj[this[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isObject(obj))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
obj[this[i]] = value;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
var invalidPath = new Path('', constructorIsPrivate);
|
|
||||||
invalidPath.valid = false;
|
|
||||||
invalidPath.getValueFrom = invalidPath.setValueFrom = function () { };
|
|
||||||
|
|
||||||
// Export the observe-js object for **Node.js**, with
|
|
||||||
// backwards-compatibility for the old `require()` API. If we're in
|
|
||||||
// the browser, export as a global object.
|
|
||||||
|
|
||||||
var expose = global;
|
|
||||||
|
|
||||||
if (typeof exports !== 'undefined') {
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
|
||||||
expose = exports = module.exports;
|
|
||||||
}
|
|
||||||
expose = exports;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expose.Path = Path;
|
while (mode) {
|
||||||
|
index++;
|
||||||
|
c = path[index];
|
||||||
|
|
||||||
})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
|
if (c == '\\' && maybeUnescapeQuote(mode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
type = getPathCharType(c);
|
||||||
|
typeMap = pathStateMachine[mode];
|
||||||
|
transition = typeMap[type] || typeMap['else'] || 'error';
|
||||||
|
|
||||||
|
if (transition == 'error')
|
||||||
|
return; // parse error;
|
||||||
|
|
||||||
|
mode = transition[0];
|
||||||
|
action = actions[transition[1]] || noop;
|
||||||
|
newChar = transition[2] === undefined ? c : transition[2];
|
||||||
|
action();
|
||||||
|
|
||||||
|
if (mode === 'afterPath') {
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return; // parse error
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIdent(s) {
|
||||||
|
return identRegExp.test(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
var constructorIsPrivate = {};
|
||||||
|
|
||||||
|
function Path(parts, privateToken) {
|
||||||
|
if (privateToken !== constructorIsPrivate)
|
||||||
|
throw Error('Use Path.get to retrieve path objects');
|
||||||
|
|
||||||
|
for (var i = 0; i < parts.length; i++) {
|
||||||
|
this.push(String(parts[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasEval && this.length) {
|
||||||
|
this.getValueFrom = this.compiledGetValueFromFn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(rafaelw): Make simple LRU cache
|
||||||
|
var pathCache = {};
|
||||||
|
|
||||||
|
function getPath(pathString) {
|
||||||
|
if (pathString instanceof Path)
|
||||||
|
return pathString;
|
||||||
|
|
||||||
|
if (pathString == null || pathString.length == 0)
|
||||||
|
pathString = '';
|
||||||
|
|
||||||
|
if (typeof pathString != 'string') {
|
||||||
|
if (isIndex(pathString.length)) {
|
||||||
|
// Constructed with array-like (pre-parsed) keys
|
||||||
|
return new Path(pathString, constructorIsPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
pathString = String(pathString);
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = pathCache[pathString];
|
||||||
|
if (path)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
var parts = parsePath(pathString);
|
||||||
|
if (!parts)
|
||||||
|
return invalidPath;
|
||||||
|
|
||||||
|
var path = new Path(parts, constructorIsPrivate);
|
||||||
|
pathCache[pathString] = path;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path.get = getPath;
|
||||||
|
|
||||||
|
function formatAccessor(key) {
|
||||||
|
if (isIndex(key)) {
|
||||||
|
return '[' + key + ']';
|
||||||
|
} else {
|
||||||
|
return '["' + key.replace(/"/g, '\\"') + '"]';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Path.prototype = createObject({
|
||||||
|
__proto__: [],
|
||||||
|
valid: true,
|
||||||
|
|
||||||
|
toString: function () {
|
||||||
|
var pathString = '';
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
var key = this[i];
|
||||||
|
if (isIdent(key)) {
|
||||||
|
pathString += i ? '.' + key : key;
|
||||||
|
} else {
|
||||||
|
pathString += formatAccessor(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathString;
|
||||||
|
},
|
||||||
|
|
||||||
|
getValueFrom: function (obj, directObserver) {
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
if (obj == null)
|
||||||
|
return;
|
||||||
|
obj = obj[this[i]];
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
iterateObjects: function (obj, observe) {
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
if (i)
|
||||||
|
obj = obj[this[i - 1]];
|
||||||
|
if (!isObject(obj))
|
||||||
|
return;
|
||||||
|
observe(obj, this[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compiledGetValueFromFn: function () {
|
||||||
|
var str = '';
|
||||||
|
var pathString = 'obj';
|
||||||
|
str += 'if (obj != null';
|
||||||
|
var i = 0;
|
||||||
|
var key;
|
||||||
|
for (; i < (this.length - 1) ; i++) {
|
||||||
|
key = this[i];
|
||||||
|
pathString += isIdent(key) ? '.' + key : formatAccessor(key);
|
||||||
|
str += ' &&\n ' + pathString + ' != null';
|
||||||
|
}
|
||||||
|
str += ')\n';
|
||||||
|
|
||||||
|
var key = this[i];
|
||||||
|
pathString += isIdent(key) ? '.' + key : formatAccessor(key);
|
||||||
|
|
||||||
|
str += ' return ' + pathString + ';\nelse\n return undefined;';
|
||||||
|
return new Function('obj', str);
|
||||||
|
},
|
||||||
|
|
||||||
|
setValueFrom: function (obj, value) {
|
||||||
|
if (!this.length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < this.length - 1; i++) {
|
||||||
|
if (!isObject(obj))
|
||||||
|
return false;
|
||||||
|
obj = obj[this[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isObject(obj))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
obj[this[i]] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var invalidPath = new Path('', constructorIsPrivate);
|
||||||
|
invalidPath.valid = false;
|
||||||
|
invalidPath.getValueFrom = invalidPath.setValueFrom = function () { };
|
||||||
|
|
||||||
|
exports.Path = Path;
|
||||||
|
Reference in New Issue
Block a user