UI: Refactor SCADA editor highlighting to support Safari on iOS versions 16.3 and below
This commit is contained in:
parent
174166d9a1
commit
00d6f7d5be
@ -30,8 +30,7 @@
|
||||
<tb-js-func #tagFunctionComponent
|
||||
minHeight="300px"
|
||||
formControlName="tagFunction"
|
||||
[objectHighlightRules]="objectHighlightRules"
|
||||
[propertyHighlightRules]="propertyHighlightRules"
|
||||
[highlightRules]="highlightRules"
|
||||
[editorCompleter]="completer"
|
||||
[functionArgs]="tagFunctionArgs"
|
||||
[helpId]="tagFunctionHelpId">
|
||||
|
||||
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,8 +80,7 @@
|
||||
<tb-js-func formControlName="stateRenderFunction"
|
||||
minHeight="300px"
|
||||
[editorCompleter]="generalStateRenderFunctionCompleter"
|
||||
[objectHighlightRules]="scadaSymbolGeneralStateRenderHighlightRules"
|
||||
[propertyHighlightRules]="scadaSymbolGeneralStateRenderPropertiesHighlightRules"
|
||||
[highlightRules]="highlightRules"
|
||||
[functionArgs]="['ctx', 'svg']"
|
||||
helpId="scada/symbol_state_render_fn">
|
||||
</tb-js-func>
|
||||
|
||||
@ -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<AppState>,
|
||||
private fb: UntypedFormBuilder,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<string>;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -352,8 +352,15 @@ export class Range implements Ace.Range {
|
||||
|
||||
}
|
||||
|
||||
export interface TbHighlightRule {
|
||||
class: string;
|
||||
regex: RegExp;
|
||||
export interface AceHighlightRules {
|
||||
[group: string]: Array<AceHighlightRule>;
|
||||
}
|
||||
|
||||
export interface AceHighlightRule {
|
||||
regex: RegExp | string;
|
||||
token: string;
|
||||
next?: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user