diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.html b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.html index 27c22df7a8..940be57364 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.html +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.html @@ -30,8 +30,7 @@ diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.ts b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.ts index d46ba364d7..3da729c442 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.ts +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata-tag-function-panel.component.ts @@ -28,12 +28,10 @@ import { TbPopoverComponent } from '@shared/components/popover.component'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { WidgetService } from '@core/http/widget.service'; import { TbEditorCompleter } from '@shared/models/ace/completion.models'; -import { TbHighlightRule } from '@shared/models/ace/ace.models'; +import { AceHighlightRules } from '@shared/models/ace/ace.models'; import { scadaSymbolClickActionHighlightRules, - scadaSymbolClickActionPropertiesHighlightRules, - scadaSymbolElementStateRenderHighlightRules, - scadaSymbolElementStateRenderPropertiesHighlightRules + scadaSymbolRenderFunctionHighlightRules } from '@home/pages/scada-symbol/scada-symbol-editor.models'; import { JsFuncComponent } from '@shared/components/js-func.component'; @@ -79,9 +77,7 @@ export class ScadaSymbolMetadataTagFunctionPanelComponent implements OnInit, Aft tagFunctionHelpId: string; - objectHighlightRules: TbHighlightRule[]; - - propertyHighlightRules: TbHighlightRule[]; + highlightRules: AceHighlightRules; constructor(private fb: UntypedFormBuilder, private widgetService: WidgetService) { @@ -99,14 +95,12 @@ export class ScadaSymbolMetadataTagFunctionPanelComponent implements OnInit, Aft if (this.tagFunctionType === 'renderFunction') { this.panelTitle = 'scada.state-render-function'; this.tagFunctionArgs = ['ctx', 'element']; - this.objectHighlightRules = scadaSymbolElementStateRenderHighlightRules; - this.propertyHighlightRules = scadaSymbolElementStateRenderPropertiesHighlightRules; + this.highlightRules = scadaSymbolRenderFunctionHighlightRules; this.tagFunctionHelpId = 'scada/tag_state_render_fn'; } else if (this.tagFunctionType === 'clickAction') { this.panelTitle = 'scada.tag.on-click-action'; this.tagFunctionArgs = ['ctx', 'element', 'event']; - this.objectHighlightRules = scadaSymbolClickActionHighlightRules; - this.propertyHighlightRules = scadaSymbolClickActionPropertiesHighlightRules; + this.highlightRules = scadaSymbolClickActionHighlightRules; this.tagFunctionHelpId = 'scada/tag_click_action_fn'; } } diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.html b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.html index 9e5d22fa94..67c77f7f2a 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.html +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.html @@ -80,8 +80,7 @@ diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.ts b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.ts index f5ecaab3d2..a5d38991b9 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.ts +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-metadata.component.ts @@ -49,8 +49,7 @@ import { elementStateRenderFunctionCompletions, generalStateRenderFunctionCompletions, scadaSymbolContextCompletion, - scadaSymbolGeneralStateRenderHighlightRules, - scadaSymbolGeneralStateRenderPropertiesHighlightRules + scadaSymbolGeneralStateHighlightRules } from '@home/pages/scada-symbol/scada-symbol-editor.models'; import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe'; import { IAliasController } from '@core/api/widget-api.models'; @@ -122,9 +121,7 @@ export class ScadaSymbolMetadataComponent extends PageComponent implements OnIni elementStateRenderFunctionCompleter: TbEditorCompleter; clickActionFunctionCompleter: TbEditorCompleter; - scadaSymbolGeneralStateRenderHighlightRules = scadaSymbolGeneralStateRenderHighlightRules; - - scadaSymbolGeneralStateRenderPropertiesHighlightRules = scadaSymbolGeneralStateRenderPropertiesHighlightRules; + highlightRules = scadaSymbolGeneralStateHighlightRules; constructor(protected store: Store, private fb: UntypedFormBuilder, diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol-editor.models.ts b/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol-editor.models.ts index ddc935d202..433e311fb7 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol-editor.models.ts +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol-editor.models.ts @@ -34,7 +34,7 @@ import { } from '@home/components/widget/lib/scada/scada-symbol.models'; import { TbEditorCompletion, TbEditorCompletions } from '@shared/models/ace/completion.models'; import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe'; -import { TbHighlightRule } from '@shared/models/ace/ace.models'; +import { AceHighlightRule, AceHighlightRules } from '@shared/models/ace/ace.models'; import { ValueType } from '@shared/models/constants'; import ITooltipsterInstance = JQueryTooltipster.ITooltipsterInstance; import TooltipPositioningSide = JQueryTooltipster.TooltipPositioningSide; @@ -916,91 +916,184 @@ export class ScadaSymbolElement { } -const scadaSymbolCtxObjectHighlightRules: TbHighlightRule[] = [ - { - class: 'scada-symbol-ctx', - regex: /(?<=\W|^)(ctx)(?=\W|$)\b/ - } -]; +const identifierRe = /[a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*/; -export const scadaSymbolGeneralStateRenderHighlightRules: TbHighlightRule[] = - scadaSymbolCtxObjectHighlightRules.concat({ - class: 'scada-symbol-svg', - regex: /(?<=\W|^)(svg)(?=\W|$)\b/ - }); +const dotOperatorHighlightRule: AceHighlightRule = { + token: 'punctuation.operator', + regex: /[.](?![.])/, +}; -export const scadaSymbolElementStateRenderHighlightRules: TbHighlightRule[] = - scadaSymbolCtxObjectHighlightRules.concat({ - class: 'scada-symbol-element', - regex: /(?<=\W|^)(element)(?=\W|$)\b/ - }); +const endGroupHighlightRule: AceHighlightRule = { + regex: '', + token: 'empty', + next: 'no_regex' +}; -export const scadaSymbolClickActionHighlightRules: TbHighlightRule[] = - scadaSymbolElementStateRenderHighlightRules.concat({ - class: 'scada-symbol-event', - regex: /(?<=\W|^)(event)(?=\W|$)\b/ - }); +const scadaSymbolCtxObjectHighlightRule: AceHighlightRule = { + token: 'tb.scada-symbol-ctx', + regex: /\bctx\b/, + next: 'scadaSymbolCtxApi' +}; -const scadaSymbolCtxPropertyHighlightRules: TbHighlightRule[] = [ - { - class: 'scada-symbol-ctx-properties', - regex: /(?<=ctx\.)(properties)\b/ - }, - { - class: 'scada-symbol-ctx-tags', - regex: /(?<=ctx\.)(tags)\b/ - }, - { - class: 'scada-symbol-ctx-values', - regex: /(?<=ctx\.)(values)\b/ - }, - { - class: 'scada-symbol-ctx-api', - regex: /(?<=ctx\.)(api)\b/ - }, - { - class: 'scada-symbol-ctx-svg', - regex: /(?<=ctx\.)(svg)\b/ - }, - { - class: 'scada-symbol-ctx-property', - regex: /(?<=ctx\.properties\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }, - { - class: 'scada-symbol-ctx-tag', - regex: /(?<=ctx\.tags\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }, - { - class: 'scada-symbol-ctx-value', - regex: /(?<=ctx\.values\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }, - { - class: 'scada-symbol-ctx-api-method', - regex: /(?<=ctx\.api\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }, - { - class: 'scada-symbol-ctx-svg-method', - regex: /(?<=ctx\.svg\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - } -]; +const scadaSymbolSVGHighlightRule: AceHighlightRule = { + token: 'tb.scada-symbol-svg', + regex: /\bsvg\b/, + next: 'scadaSymbolSVGApi' +}; -export const scadaSymbolGeneralStateRenderPropertiesHighlightRules: TbHighlightRule[] = - scadaSymbolCtxPropertyHighlightRules.concat({ - class: 'scada-symbol-svg-properties', - regex: /(?<=svg\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }); +const scadaSymbolElementHighlightRule: AceHighlightRule = { + token: 'tb.scada-symbol-element', + regex: /\belement\b/, + next: 'scadaSymbolElementApi' +}; -export const scadaSymbolElementStateRenderPropertiesHighlightRules: TbHighlightRule[] = - scadaSymbolCtxPropertyHighlightRules.concat({ - class: 'scada-symbol-element-properties', - regex: /(?<=element\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }); +const scadaSymbolEventHighlightRule: AceHighlightRule = { + token: 'tb.scada-symbol-event', + regex: /\bevent\b/, + next: 'scadaSymbolEventApi' +}; -export const scadaSymbolClickActionPropertiesHighlightRules: TbHighlightRule[] = - scadaSymbolElementStateRenderPropertiesHighlightRules.concat({ - class: 'scada-symbol-event-properties', - regex: /(?<=event\.)([a-zA-Z$_\u00a1-\uffff][a-zA-Z\d$_\u00a1-\uffff]*)\b/ - }); +const scadaSymbolCtxApiHighlightRules: AceHighlightRules = { + scadaSymbolCtxApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-ctx-properties', + regex: /properties/, + next: 'scadaSymbolCtxPropertiesApi' + }, + { + token: 'tb.scada-symbol-ctx-tags', + regex: /tags/, + next: 'scadaSymbolCtxTagsApi' + }, + { + token: 'tb.scada-symbol-ctx-values', + regex: /values/, + next: 'scadaSymbolCtxValuesApi' + }, + { + token: 'tb.scada-symbol-ctx-api', + regex: /api/, + next: 'scadaSymbolCtxApiMethodApi' + }, + { + token: 'tb.scada-symbol-ctx-svg', + regex: /svg/, + next: 'scadaSymbolCtxSVGMethodApi' + }, + endGroupHighlightRule + ], + scadaSymbolCtxPropertiesApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-ctx-property', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ], + scadaSymbolCtxTagsApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-ctx-tag', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ], + scadaSymbolCtxValuesApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-ctx-value', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ], + scadaSymbolCtxApiMethodApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-ctx-api-method', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ], + scadaSymbolCtxSVGMethodApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-ctx-svg-method', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ] +}; + +const scadaSymbolSVGPropertyHighlightRules: AceHighlightRules = { + scadaSymbolSVGApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-svg-properties', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ] +}; + +const scadaSymbolElementPropertyHighlightRules: AceHighlightRules = { + scadaSymbolElementApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-element-properties', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ] +}; + +const scadaSymbolEventPropertyHighlightRules: AceHighlightRules = { + scadaSymbolEventApi: [ + dotOperatorHighlightRule, + { + token: 'tb.scada-symbol-event-properties', + regex: identifierRe, + next: 'no_regex' + }, + endGroupHighlightRule + ] +}; + +export const scadaSymbolGeneralStateHighlightRules: AceHighlightRules = { + start: [ + scadaSymbolCtxObjectHighlightRule, + scadaSymbolSVGHighlightRule + ], + ...scadaSymbolCtxApiHighlightRules, + ...scadaSymbolSVGPropertyHighlightRules +}; + +export const scadaSymbolRenderFunctionHighlightRules: AceHighlightRules = { + no_regex: [ + scadaSymbolCtxObjectHighlightRule, + scadaSymbolElementHighlightRule + ], + ...scadaSymbolCtxApiHighlightRules, + ...scadaSymbolElementPropertyHighlightRules +}; + +export const scadaSymbolClickActionHighlightRules: AceHighlightRules = { + start: [ + scadaSymbolCtxObjectHighlightRule, + scadaSymbolElementHighlightRule, + scadaSymbolEventHighlightRule + ], + ...scadaSymbolCtxApiHighlightRules, + ...scadaSymbolElementPropertyHighlightRules, + ...scadaSymbolEventPropertyHighlightRules +}; export const generalStateRenderFunctionCompletions = (ctxCompletion: TbEditorCompletion): TbEditorCompletions => ({ ctx: ctxCompletion, diff --git a/ui-ngx/src/app/shared/components/js-func.component.ts b/ui-ngx/src/app/shared/components/js-func.component.ts index 8c3fa0a423..e15535391f 100644 --- a/ui-ngx/src/app/shared/components/js-func.component.ts +++ b/ui-ngx/src/app/shared/components/js-func.component.ts @@ -25,15 +25,15 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; -import { ControlValueAccessor, UntypedFormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, Validator } from '@angular/forms'; +import { ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, UntypedFormControl, Validator } from '@angular/forms'; import { Ace } from 'ace-builds'; -import { getAce, Range, TbHighlightRule } from '@shared/models/ace/ace.models'; +import { AceHighlightRules, getAce, Range } from '@shared/models/ace/ace.models'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { ActionNotificationHide, ActionNotificationShow } from '@core/notification/notification.actions'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { UtilsService } from '@core/services/utils.service'; -import { deepClone, guid, isUndefined } from '@app/core/utils'; +import { guid, isUndefined } from '@app/core/utils'; import { TranslateService } from '@ngx-translate/core'; import { CancelAnimationFrame, RafService } from '@core/services/raf.service'; import { ResizeObserver } from '@juggle/resize-observer'; @@ -90,9 +90,7 @@ export class JsFuncComponent implements OnInit, OnDestroy, ControlValueAccessor, @Input() editorCompleter: TbEditorCompleter; - @Input() propertyHighlightRules: TbHighlightRule[]; - - @Input() objectHighlightRules: TbHighlightRule[]; + @Input() highlightRules: AceHighlightRules; @Input() globalVariables: Array; @@ -220,27 +218,16 @@ export class JsFuncComponent implements OnInit, OnDestroy, ControlValueAccessor, }); } // @ts-ignore - if ((this.propertyHighlightRules?.length || this.objectHighlightRules?.length) && !!this.jsEditor.session.$mode) { + if (!!this.highlightRules && !!this.jsEditor.session.$mode) { // @ts-ignore const newMode = new this.jsEditor.session.$mode.constructor(); newMode.$highlightRules = new newMode.HighlightRules(); - if (this.propertyHighlightRules?.length) { - const propertiesRules: { token: string; regex: RegExp }[] = newMode.$highlightRules.$rules.property; - const index = propertiesRules.findIndex(p => p.token === 'support.constant'); - const additionalPropertyRules: { token: string; regex: RegExp }[] = this.propertyHighlightRules.map(r => ({ - token: `tb.${r.class}`, - regex: r.regex - })); - propertiesRules.splice(index, 0, ...additionalPropertyRules); - } - if (this.objectHighlightRules?.length) { - const noRegexRules: { token: string; regex: RegExp }[] = newMode.$highlightRules.$rules.no_regex; - const index = noRegexRules.findIndex(p => Array.isArray(p.token) && p.token[0] === 'support.constant'); - const additionalNoRegexRules: { token: string; regex: RegExp }[] = this.objectHighlightRules.map(r => ({ - token: `tb.${r.class}`, - regex: r.regex - })); - noRegexRules.splice(index, 0, ...additionalNoRegexRules); + for(const group in this.highlightRules) { + if(!!newMode.$highlightRules.$rules[group]) { + newMode.$highlightRules.$rules[group].unshift(...this.highlightRules[group]); + } else { + newMode.$highlightRules.$rules[group] = this.highlightRules[group]; + } } // @ts-ignore this.jsEditor.session.$onChangeMode(newMode); diff --git a/ui-ngx/src/app/shared/models/ace/ace.models.ts b/ui-ngx/src/app/shared/models/ace/ace.models.ts index 221e68564b..381d897066 100644 --- a/ui-ngx/src/app/shared/models/ace/ace.models.ts +++ b/ui-ngx/src/app/shared/models/ace/ace.models.ts @@ -352,8 +352,15 @@ export class Range implements Ace.Range { } -export interface TbHighlightRule { - class: string; - regex: RegExp; +export interface AceHighlightRules { + [group: string]: Array; } +export interface AceHighlightRule { + regex: RegExp | string; + token: string; + next?: string; +} + + +