1 |
|
2 | const expressionSymbolsRegex = /[\+\-\*\/%\?:<>=!\|&\(\)^~]|^`.*\$\{.+\}.*`$/;
|
3 | export var bindingConstants;
|
4 | (function (bindingConstants) {
|
5 | bindingConstants.sourceProperty = 'sourceProperty';
|
6 | bindingConstants.targetProperty = 'targetProperty';
|
7 | bindingConstants.expression = 'expression';
|
8 | bindingConstants.twoWay = 'twoWay';
|
9 | bindingConstants.source = 'source';
|
10 | bindingConstants.bindingValueKey = '$value';
|
11 | bindingConstants.parentValueKey = '$parent';
|
12 | bindingConstants.parentsValueKey = '$parents';
|
13 | bindingConstants.newPropertyValueKey = '$newPropertyValue';
|
14 | })(bindingConstants || (bindingConstants = {}));
|
15 | const hasEqualSignRegex = /=+/;
|
16 | const equalSignComparisionOperatorsRegex = /(==|===|>=|<=|!=|!==)/;
|
17 |
|
18 | export const parentsRegex = /\$parents\s*\[\s*(['"]*)\w*\1\s*\]/g;
|
19 | function isNamedParam(value) {
|
20 | const equalSignIndex = value.search(hasEqualSignRegex);
|
21 | if (equalSignIndex > -1) {
|
22 | const equalSignSurround = value.substr(equalSignIndex > 0 ? equalSignIndex - 1 : 0, 3);
|
23 | if (equalSignSurround.search(equalSignComparisionOperatorsRegex) === -1) {
|
24 | return true;
|
25 | }
|
26 | }
|
27 | return false;
|
28 | }
|
29 | function areNamedParams(params) {
|
30 | for (let i = 0; i < params.length; i++) {
|
31 | if (isNamedParam(params[i])) {
|
32 | return true;
|
33 | }
|
34 | }
|
35 | return false;
|
36 | }
|
37 | const namedParamConstants = {
|
38 | propName: 'propName',
|
39 | propValue: 'propValue',
|
40 | };
|
41 | function getPropertyNameValuePair(param, knownOptions, callback) {
|
42 | let nameValuePair = {};
|
43 | let propertyName = param.substr(0, param.indexOf('=')).trim();
|
44 | const propertyValue = param.substr(param.indexOf('=') + 1).trim();
|
45 | if (knownOptions) {
|
46 | if (!propertyName) {
|
47 | propertyName = knownOptions.defaultProperty;
|
48 | }
|
49 | else {
|
50 | propertyName = propertyName in knownOptions ? propertyName : null;
|
51 | }
|
52 | }
|
53 | if (propertyName) {
|
54 | if (callback) {
|
55 | nameValuePair = callback(propertyName, propertyValue);
|
56 | }
|
57 | else {
|
58 | nameValuePair[namedParamConstants.propName] = propertyName;
|
59 | nameValuePair[namedParamConstants.propValue] = propertyValue;
|
60 | }
|
61 | return nameValuePair;
|
62 | }
|
63 | return null;
|
64 | }
|
65 | function parseNamedProperties(parameterList, knownOptions, callback) {
|
66 | const result = {};
|
67 | let nameValuePair;
|
68 | for (let i = 0; i < parameterList.length; i++) {
|
69 | nameValuePair = getPropertyNameValuePair(parameterList[i], knownOptions, callback);
|
70 | if (nameValuePair) {
|
71 | result[nameValuePair[namedParamConstants.propName]] = nameValuePair[namedParamConstants.propValue];
|
72 | }
|
73 | }
|
74 | return result;
|
75 | }
|
76 | function getParamsArray(value) {
|
77 | const result = [];
|
78 | let skipComma = 0;
|
79 | let indexReached = 0;
|
80 | let singleQuoteBlock = false;
|
81 | let doubleQuoteBlock = false;
|
82 | for (let i = 0; i < value.length; i++) {
|
83 | if (value[i] === '"') {
|
84 | doubleQuoteBlock = !doubleQuoteBlock;
|
85 | }
|
86 | if (value[i] === "'") {
|
87 | singleQuoteBlock = !singleQuoteBlock;
|
88 | }
|
89 | if (value[i] === '(' || value[i] === '[') {
|
90 | skipComma++;
|
91 | }
|
92 | if (value[i] === ')' || value[i] === ']') {
|
93 | skipComma--;
|
94 | }
|
95 | if (value[i] === ',' && skipComma === 0 && !(singleQuoteBlock || doubleQuoteBlock)) {
|
96 | result.push(value.substr(indexReached, i - indexReached));
|
97 | indexReached = i + 1;
|
98 | }
|
99 | }
|
100 | result.push(value.substr(indexReached));
|
101 | return result;
|
102 | }
|
103 | function isExpression(expression) {
|
104 | return expression.search(expressionSymbolsRegex) > -1;
|
105 | }
|
106 | export function getBindingOptions(name, value) {
|
107 | let namedParams = [];
|
108 | const params = getParamsArray(value);
|
109 | if (!areNamedParams(params)) {
|
110 | if (params.length === 1) {
|
111 | const trimmedValue = params[0].trim();
|
112 | let sourceProp;
|
113 | if (isExpression(trimmedValue)) {
|
114 | sourceProp = bindingConstants.bindingValueKey;
|
115 | namedParams.push(bindingConstants.expression + ' = ' + trimmedValue);
|
116 | }
|
117 | else {
|
118 | sourceProp = trimmedValue;
|
119 | }
|
120 | namedParams.push(bindingConstants.sourceProperty + ' = ' + sourceProp);
|
121 | namedParams.push(bindingConstants.twoWay + ' = true');
|
122 | }
|
123 | else {
|
124 | namedParams.push(bindingConstants.sourceProperty + ' = ' + params[0].trim());
|
125 | namedParams.push(bindingConstants.expression + ' = ' + params[1].trim());
|
126 | const twoWay = params[2] ? params[2].toLowerCase().trim() === 'true' : true;
|
127 | namedParams.push(bindingConstants.twoWay + ' = ' + twoWay);
|
128 | }
|
129 | }
|
130 | else {
|
131 | namedParams = params;
|
132 | }
|
133 | const bindingPropertyHandler = function (prop, value) {
|
134 | const result = {};
|
135 | result[namedParamConstants.propName] = prop;
|
136 | if (prop === bindingConstants.twoWay) {
|
137 |
|
138 | if (value === 'true') {
|
139 | result[namedParamConstants.propValue] = true;
|
140 | }
|
141 | else {
|
142 | result[namedParamConstants.propValue] = false;
|
143 | }
|
144 | }
|
145 | else {
|
146 | result[namedParamConstants.propValue] = value;
|
147 | }
|
148 | return result;
|
149 | };
|
150 | const bindingOptionsParameters = parseNamedProperties(namedParams, xmlBindingProperties, bindingPropertyHandler);
|
151 | const bindOptions = {
|
152 | targetProperty: name,
|
153 | };
|
154 | for (const prop in bindingOptionsParameters) {
|
155 | if (bindingOptionsParameters.hasOwnProperty(prop)) {
|
156 | bindOptions[prop] = bindingOptionsParameters[prop];
|
157 | }
|
158 | }
|
159 | if (bindOptions[bindingConstants.twoWay] === undefined) {
|
160 | bindOptions[bindingConstants.twoWay] = true;
|
161 | }
|
162 | return bindOptions;
|
163 | }
|
164 | const xmlBindingProperties = {
|
165 | sourceProperty: true,
|
166 | expression: true,
|
167 | twoWay: true,
|
168 | source: true,
|
169 | defaultProperty: bindingConstants.sourceProperty,
|
170 | };
|
171 |
|
\ | No newline at end of file |