UNPKG

devexpress-richedit

Version:

DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.

149 lines (148 loc) 5.8 kB
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) { 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(parameters[1]?.text)) { leftExpression = new IfExpressionParameter(parameters[0]?.text, parameters[0]?.quoted); trueText = parameters[1]?.text; falseText = parameters[2]?.text; } else { leftExpression = new IfExpressionParameter(parameters[0]?.text, parameters[0]?.quoted); operator = parameters[1]?.text; rightExpression = new IfExpressionParameter(parameters[2]?.text, parameters[2]?.quoted); trueText = parameters[3]?.text; falseText = parameters[4]?.text; } return new IfExpression(operator, leftExpression, rightExpression, trueText, falseText); } } export class IfExpression { operator; leftExpression; rightExpression; trueText; falseText; static operators = ["<", ">", "=", "<=", ">=", "<>"]; 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; } } export class IfExpressionParameter { text; number; isNumber; 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 ?? "IF field error: Invalid comparison operator"); Object.setPrototypeOf(this, IfExpressionInvalidOperatorError.prototype); } } export class IfExpressionTooManyParametersError extends IfExpressionError { constructor(message) { super(message ?? "IF field error: Too many parameters"); Object.setPrototypeOf(this, IfExpressionTooManyParametersError.prototype); } } export class IfExpressionMissingParametersError extends IfExpressionError { constructor(message) { super(message ?? "IF field error: Missing parameter(s)"); Object.setPrototypeOf(this, IfExpressionMissingParametersError.prototype); } }