salix/client/core/src/lib/interpolate.js

203 lines
6.5 KiB
JavaScript
Raw Normal View History

2017-02-07 13:34:26 +00:00
import {module} from '../module';
import {ng} from 'vendor';
import * as util from './util';
export const NAME = util.getProviderName('interpolate');
function minErr() {}
function stringify(value) {
if (value === null) { // null || undefined
return '';
}
switch (typeof value) {
case 'string':
break;
case 'number':
value = String(value);
break;
default:
value = angular.toJson(value);
}
return value;
}
var $interpolateMinErr = ng.angular.$interpolateMinErr = ng.$$minErr('$interpolate');
$interpolateMinErr.throwNoconcat = function(text) {
throw $interpolateMinErr('noconcat',
'Error while interpolating: {0}\nStrict Contextual Escaping disallows ' +
'interpolations that concatenate multiple expressions when a trusted value is ' +
'required. See http://docs.angularjs.org/api/ng.$sce', text);
};
$interpolateMinErr.interr = function(text, err) {
return $interpolateMinErr('interr', 'Can\'t interpolate: {0}\n{1}', text, err.toString());
};
function $get($parse, $exceptionHandler, $sce) {
var startSymbolLength = this._startSymbol.length,
endSymbolLength = this._endSymbol.length,
escapedStartRegexp = new RegExp(this._startSymbol.replace(/./g, escape), 'g'),
escapedEndRegexp = new RegExp(this._endSymbol.replace(/./g, escape), 'g'),
self = this;
function escape(ch) {
return '\\\\\\' + ch;
}
function unescapeText(text) {
return text.replace(escapedStartRegexp, self._startSymbol)
.replace(escapedEndRegexp, self._endSymbol);
}
// TODO: this is the same as the constantWatchDelegate in parse.js
function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {
var unwatch = scope.$watch(function constantInterpolateWatch(scope) {
unwatch();
return constantInterp(scope);
}, listener, objectEquality);
return unwatch;
}
function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
// Provide a quick exit and simplified result function for text with no interpolation
if (!text.length || text.indexOf(self._startSymbol) === -1) {
var constantInterp;
if (!mustHaveExpression) {
var unescapedText = unescapeText(text);
constantInterp = valueFn(unescapedText);
constantInterp.exp = text;
constantInterp.expressions = [];
constantInterp.$$watchDelegate = constantWatchDelegate;
}
return constantInterp;
}
allOrNothing = Boolean(allOrNothing);
var startIndex,
endIndex,
index = 0,
expressions = [],
parseFns = [],
textLength = text.length,
exp,
concat = [],
expressionPositions = [];
while (index < textLength) {
if (((startIndex = text.indexOf(self._startSymbol, index)) !== -1) &&
((endIndex = text.indexOf(self._endSymbol, startIndex + startSymbolLength)) !== -1)) {
if (index !== startIndex) {
concat.push(unescapeText(text.substring(index, startIndex)));
}
exp = text.substring(startIndex + startSymbolLength, endIndex);
expressions.push(exp);
parseFns.push($parse(exp, parseStringifyInterceptor));
index = endIndex + endSymbolLength;
expressionPositions.push(concat.length);
concat.push('');
} else {
// we did not find an interpolation, so we have to add the remainder to the separators array
if (index !== textLength) {
concat.push(unescapeText(text.substring(index)));
}
break;
}
}
if (trustedContext && concat.length > 1) {
$interpolateMinErr.throwNoconcat(text);
}
if (!mustHaveExpression || expressions.length) {
var compute = function(values) {
for (var i = 0, ii = expressions.length; i < ii; i++) {
if (allOrNothing && isUndefined(values[i])) return;
concat[expressionPositions[i]] = values[i];
}
return concat.join('');
};
var getValue = function(value) {
return trustedContext ?
$sce.getTrusted(trustedContext, value) :
$sce.valueOf(value);
};
return angular.extend(function interpolationFn(context) {
var i = 0;
var ii = expressions.length;
var values = new Array(ii);
try {
for (; i < ii; i++) {
values[i] = parseFns[i](context);
}
return compute(values);
} catch (err) {
$exceptionHandler($interpolateMinErr.interr(text, err));
}
}, {
// all of these properties are undocumented for now
exp: text, // just for compatibility with regular watchers created via $watch
expressions: expressions
});
}
function parseStringifyInterceptor(value) {
try {
value = getValue(value);
return allOrNothing && !isDefined(value) ? value : stringify(value);
} catch (err) {
$exceptionHandler($interpolateMinErr.interr(text, err));
}
}
}
$interpolate.startSymbol = function() {
return startSymbol;
};
$interpolate.endSymbol = function() {
return endSymbol;
};
return $interpolate;
}
$get.$inject = ['$parse', '$exceptionHandler', '$sce'];
export class Interpolate
{
constructor() {
this._startSymbol = '*[';
this._endSymbol = ']*';
}
set startSymbol(value) {
if (value) {
this._startSymbol = value;
return this;
} else {
return this._startSymbol;
}
}
set endSymbol(value) {
if (value) {
this._endSymbol = value;
return this;
} else {
return this._endSymbol;
}
}
}
Interpolate.prototype.$get = $get;
var interpolate = new Interpolate();
module.provider(NAME, () => interpolate);