devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
142 lines (141 loc) • 6.41 kB
JavaScript
import { FieldName } from '../names';
import { FieldCodeParserClientUpdatingBase } from './field-code-parser-client-updating-base';
export class FieldCodeParserIf extends FieldCodeParserClientUpdatingBase {
get name() { return FieldName.If; }
fillResult() {
this.setInputPositionState();
let result = null;
try {
result = this.getResult();
}
catch (err) {
if (err instanceof IfExpressionError) {
result = err.message;
}
}
finally {
if (result) {
this.replaceTextByInterval(this.getTopField().getResultInterval(), result);
}
return true;
}
}
getResult() {
const expression = this.parseParameters(this.parameterInfoList);
return expression.evaluate();
}
parseParameters(parameters) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
if (parameters.length > 5)
throw new IfExpressionTooManyParametersError();
if (parameters.length === 0)
throw new IfExpressionMissingParametersError();
let leftExpression;
let operator;
let rightExpression;
let trueText;
let falseText;
if (parameters.length <= 3 && !IfExpression.isOperator((_a = parameters[1]) === null || _a === void 0 ? void 0 : _a.text)) {
leftExpression = new IfExpressionParameter((_b = parameters[0]) === null || _b === void 0 ? void 0 : _b.text, (_c = parameters[0]) === null || _c === void 0 ? void 0 : _c.quoted);
trueText = (_d = parameters[1]) === null || _d === void 0 ? void 0 : _d.text;
falseText = (_e = parameters[2]) === null || _e === void 0 ? void 0 : _e.text;
}
else {
leftExpression = new IfExpressionParameter((_f = parameters[0]) === null || _f === void 0 ? void 0 : _f.text, (_g = parameters[0]) === null || _g === void 0 ? void 0 : _g.quoted);
operator = (_h = parameters[1]) === null || _h === void 0 ? void 0 : _h.text;
rightExpression = new IfExpressionParameter((_j = parameters[2]) === null || _j === void 0 ? void 0 : _j.text, (_k = parameters[2]) === null || _k === void 0 ? void 0 : _k.quoted);
trueText = (_l = parameters[3]) === null || _l === void 0 ? void 0 : _l.text;
falseText = (_m = parameters[4]) === null || _m === void 0 ? void 0 : _m.text;
}
return new IfExpression(operator, leftExpression, rightExpression, trueText, falseText);
}
}
export class IfExpression {
constructor(operator, leftExpression, rightExpression, trueText = undefined, falseText = undefined) {
this.operator = operator;
this.leftExpression = leftExpression;
this.rightExpression = rightExpression;
this.trueText = trueText;
this.falseText = falseText;
}
static isOperator(operator) {
return IfExpression.operators.includes(operator);
}
evaluate() {
if (!this.operator && !this.leftExpression.isNumber) {
return this.leftExpression.text ? this.trueText : this.falseText;
}
if (!IfExpression.isOperator(this.operator)) {
throw new IfExpressionInvalidOperatorError();
}
let difference;
if (this.leftExpression.isNumber && this.rightExpression.isNumber) {
difference = this.leftExpression.number - this.rightExpression.number;
}
else {
const isEqualityOperator = this.operator === "=" || this.operator === "<>";
const compareFunction = isEqualityOperator ? IfExpression.compareStringsWithWildcards : IfExpression.compareStrings;
difference = compareFunction(this.leftExpression.text, this.rightExpression.text);
}
return this.evaluateComparison(difference) ? this.trueText : this.falseText;
}
evaluateComparison(comparisonResult) {
switch (this.operator) {
case "<":
return comparisonResult < 0;
case ">":
return comparisonResult > 0;
case "=":
return comparisonResult === 0;
case "<=":
return comparisonResult <= 0;
case ">=":
return comparisonResult >= 0;
case "<>":
return comparisonResult != 0;
default:
return false;
}
}
static compareStrings(leftValue, rightValue) {
return leftValue.localeCompare(rightValue);
}
static compareStringsWithWildcards(leftValue, rightValue) {
const escapedPattern = rightValue.replace(/[.+^${}()|[\]\\]/g, "\\$&");
const regexPattern = escapedPattern.replace(/\*/g, '.*').replace(/\?/g, '.');
const regex = new RegExp(`^${regexPattern}$`);
return regex.test(leftValue) ? 0 : 1;
}
}
IfExpression.operators = ["<", ">", "=", "<=", ">=", "<>"];
export class IfExpressionParameter {
constructor(text, isQuoted = false) {
this.text = text;
this.number = parseFloat(text);
this.isNumber = !isQuoted && !Number.isNaN(this.number);
}
}
export class IfExpressionError extends Error {
constructor(message) {
super(message);
Object.setPrototypeOf(this, IfExpressionError.prototype);
}
}
export class IfExpressionInvalidOperatorError extends IfExpressionError {
constructor(message) {
super(message !== null && message !== void 0 ? message : "IF field error: Invalid comparison operator");
Object.setPrototypeOf(this, IfExpressionInvalidOperatorError.prototype);
}
}
export class IfExpressionTooManyParametersError extends IfExpressionError {
constructor(message) {
super(message !== null && message !== void 0 ? message : "IF field error: Too many parameters");
Object.setPrototypeOf(this, IfExpressionTooManyParametersError.prototype);
}
}
export class IfExpressionMissingParametersError extends IfExpressionError {
constructor(message) {
super(message !== null && message !== void 0 ? message : "IF field error: Missing parameter(s)");
Object.setPrototypeOf(this, IfExpressionMissingParametersError.prototype);
}
}