Skip to content

Commit b0f500b

Browse files
committed
copy variable id on click
1 parent d4a7810 commit b0f500b

15 files changed

Lines changed: 72 additions & 66 deletions

File tree

editor/src/app/components/layout/header/header.component.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
1+
import { Component, inject, OnDestroy, OnInit } from '@angular/core';
22
import { NavigationEnd, Router } from '@angular/router';
33
import { TranslateService } from '@ngx-translate/core';
44
import { CookieService } from 'ngx-cookie-service';
@@ -32,6 +32,15 @@ import { AnalyticsService } from '../../../analytics';
3232
standalone: false
3333
})
3434
export class HeaderComponent implements OnInit, OnDestroy {
35+
private _auth = inject(AuthFacade);
36+
private _ui = inject(UiFacade)
37+
private _router = inject(Router);
38+
private _translate = inject(TranslateService)
39+
private _cookies = inject(CookieService);
40+
private _game = inject(GameFacade)
41+
private _analytics = inject(AnalyticsService);
42+
private _config = inject(CONFIG);
43+
3544
baseGames = getBaseGames();
3645
KNOWN_LANGUAGES = KNOWN_LANGUAGES;
3746
displaySearchHelp$ = this._ui.displaySearchHelp$;
@@ -55,17 +64,6 @@ export class HeaderComponent implements OnInit, OnDestroy {
5564
})
5665
);
5766

58-
constructor(
59-
private _auth: AuthFacade,
60-
private _ui: UiFacade,
61-
private _router: Router,
62-
private _translate: TranslateService,
63-
private _cookies: CookieService,
64-
private _game: GameFacade,
65-
private _analytics: AnalyticsService,
66-
@Inject(CONFIG) private _config: Config
67-
) {}
68-
6967
ngOnInit() {
7068
this.searchDebounced$
7169
.pipe(

editor/src/app/components/scm/key-value-editor/key-value-editor.component.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
QueryList,
99
ViewChildren,
1010
} from '@angular/core';
11+
import { isValidIdentifier } from '../../../utils';
1112

1213
export interface KeyValueEntry {
1314
key: string;
@@ -44,9 +45,10 @@ export class KeyValueEditorComponent {
4445

4546
filterQuery = '';
4647
isInvalid = false;
47-
errors: Record<'emptyKey' | 'emptyValue', boolean> = {
48+
errors: Record<'emptyKey' | 'emptyValue' | 'invalidIdentifier', boolean> = {
4849
emptyKey: false,
4950
emptyValue: false,
51+
invalidIdentifier: false,
5052
};
5153
errorMessages: string[] = [];
5254

@@ -102,10 +104,10 @@ export class KeyValueEditorComponent {
102104

103105
private updateErrors() {
104106
this.errors.emptyKey = this.entries.some((entry) => !entry.key?.trim());
105-
this.errors.emptyValue = this.entries.some(
106-
(entry) => !entry.value?.trim(),
107+
this.errors.emptyValue = this.entries.some((entry) => !entry.value?.trim());
108+
this.errors.invalidIdentifier = this.entries.some(
109+
({ value }) => !isValidIdentifier(value),
107110
);
108-
109111
this.errorMessages = Object.entries(this.errors)
110112
.filter(([_, hasError]) => hasError)
111113
.map(([errorType]) => `ui.errors.scm.${errorType}`);

editor/src/app/components/scm/scm-page/scm-page.component.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,11 @@ export class ScmPageComponent implements OnInit, AfterViewInit, OnDestroy {
111111
ngOnDestroy() {
112112
this.onDestroy$.next(undefined);
113113
this.onDestroy$.complete();
114-
this._ui.toggleCommandListElements(false);
115114
}
116115

117116
ngAfterViewInit(): void {
118117
this.detectScreenSize();
119-
this._ui.toggleCommandListElements(true);
118+
this._ui.toggleCommandListElements(false);
120119
}
121120

122121
onCancel() {

editor/src/app/components/scm/scm-view/scm-view.component.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,8 @@ export class ScmViewComponent implements OnChanges {
142142
case '"':
143143
return 'tok-str';
144144
case '$': {
145-
const refIndex = parseInt(arg.slice(1), 10);
146-
147-
if (
148-
!isNaN(refIndex) &&
149-
refIndex >= 0 &&
150-
refIndex < this.code.symbols.length
151-
) {
152-
let symbol = this.code.symbols[refIndex];
145+
const symbol = this.getSymbol(arg);
146+
if (symbol) {
153147
if (symbol.startsWith('g.') || symbol.startsWith('l.')) {
154148
return 'tok-var';
155149
}
@@ -241,19 +235,18 @@ export class ScmViewComponent implements OnChanges {
241235

242236
if (this.isRef(i) && typeof lineOffset === 'number') {
243237
const labelId = `label-${this.code.base + lineOffset}`;
238+
let text = this.escapeHtml(this.formatLabel(lineOffset));
239+
let title = `Click to view Xrefs for ${text}`;
240+
let href = this.escapeAttribute(
241+
this.toCurrentHref({ fragment: labelId }),
242+
);
243+
let id = this.escapeAttribute(labelId);
244+
let classes = 'tok-label tok-ref identifier';
244245
parts.push(
245-
`<a href="${this.escapeAttribute(
246-
this.toCurrentHref({ fragment: labelId }),
247-
)}" id="${this.escapeAttribute(labelId)}" class="tok-label tok-ref identifier">${this.escapeHtml(
248-
this.formatLabel(lineOffset),
249-
)}</a>`,
246+
`<a title="${title}" href="${href}" id="${id}" class="${classes}">${text}</a>`,
250247
);
251248
}
252249

253-
// if (this.isUnreachableInstruction(i)) {
254-
// parts.push('<div class="text-muted pt-3 pl-5">// unreachable</div>');
255-
// }
256-
257250
const activeClass =
258251
this.activeFragment === this.getLineNumberAnchorId(i) ? ' active' : '';
259252
parts.push(`<div class="line-row${activeClass}">`);
@@ -348,22 +341,32 @@ export class ScmViewComponent implements OnChanges {
348341
)}</a>`;
349342
}
350343

344+
let symbol = this.getSymbol(arg);
345+
if (symbol) {
346+
let escapedSymbol = this.escapeAttribute(symbol);
347+
return `<span title="Click to copy ${symbol} to clipboard" data-copy-text="${escapedSymbol}" class="tok ${this.getClass(arg)}">${this.escapeHtml(display)}</span>`;
348+
}
349+
351350
return `<span class="tok ${this.getClass(arg)}">${this.escapeHtml(display)}</span>`;
352351
}
353352

354-
private overlayValue(arg: number | string): string {
355-
let resolved: number | string = arg;
356-
if (typeof arg === 'string' && arg.startsWith('$')) {
357-
const refIndex = Number.parseInt(arg.slice(1), 10);
358-
if (
359-
!Number.isNaN(refIndex) &&
360-
refIndex >= 0 &&
361-
refIndex < this.code.symbols.length
362-
) {
363-
resolved = this.code.symbols[refIndex];
364-
}
353+
private getSymbol(arg: number | string): string | null {
354+
if (typeof arg !== 'string' || !arg.startsWith('$')) {
355+
return null;
365356
}
357+
const refIndex = Number.parseInt(arg.slice(1), 10);
358+
if (
359+
Number.isNaN(refIndex) ||
360+
refIndex < 0 ||
361+
refIndex >= this.code.symbols.length
362+
) {
363+
return null;
364+
}
365+
return this.code.symbols[refIndex] ?? null;
366+
}
366367

368+
private overlayValue(arg: number | string): string {
369+
const resolved = this.getSymbol(arg) ?? arg;
367370
const value = String(resolved);
368371
return this.overlay[value] ?? this.defaultOverlay(value);
369372
}

editor/src/app/components/scm/variable-editor/variable-editor.component.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ export class VariableEditorComponent {
1919

2020
@Input() set variables(value: Record<string, string>) {
2121
this._variables = value ?? {};
22-
this.entries = Object.entries(this._variables)
23-
.map(([key, val]) => ({
24-
key: this.toRawVariableKey(key),
25-
value: val,
26-
}));
22+
this.entries = Object.entries(this._variables).map(([key, value]) => ({
23+
key,
24+
value,
25+
}));
2726
}
2827

2928
get variables() {
@@ -44,14 +43,10 @@ export class VariableEditorComponent {
4443
this.hasError.emit(hasError);
4544
}
4645

47-
toRawVariableKey(key: string): string {
48-
return key.startsWith('g.') ? key.slice('g.'.length) : key;
49-
}
50-
5146
private toRecord(entries: KeyValueEntry[]): Record<string, string> {
5247
const variables: Record<string, string> = {};
5348
for (const entry of entries) {
54-
variables[`g.${entry.key}`] = entry.value ?? '';
49+
variables[entry.key] = entry.value ?? '';
5550
}
5651
return variables;
5752
}

editor/src/app/config/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { InjectionToken, NgModule } from '@angular/core';
22
import { environment } from '../../environments/environment';
33

4-
export const CONFIG = new InjectionToken('config');
4+
export const CONFIG = new InjectionToken<Config>('config');
55

66
export interface Config {
77
production: boolean;

editor/src/assets/i18n/bn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@
288288
},
289289
"scm": {
290290
"emptyKey": "Key can't be empty",
291-
"emptyValue": "Value can't be empty"
291+
"emptyValue": "Value can't be empty",
292+
"invalidIdentifier": "Value should start with a letter or _ and contain only letters, digits and _"
292293
}
293294
},
294295
"map": {

editor/src/assets/i18n/cn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@
287287
},
288288
"scm": {
289289
"emptyKey": "Key can't be empty",
290-
"emptyValue": "Value can't be empty"
290+
"emptyValue": "Value can't be empty",
291+
"invalidIdentifier": "Value should start with a letter or _ and contain only letters, digits and _"
291292
}
292293
},
293294
"map": {

editor/src/assets/i18n/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@
287287
},
288288
"scm": {
289289
"emptyKey": "Key can't be empty",
290-
"emptyValue": "Value can't be empty"
290+
"emptyValue": "Value can't be empty",
291+
"invalidIdentifier": "Value should start with a letter or _ and contain only letters, digits and _"
291292
}
292293
},
293294
"map": {

editor/src/assets/i18n/es.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@
287287
},
288288
"scm": {
289289
"emptyKey": "Key can't be empty",
290-
"emptyValue": "Value can't be empty"
290+
"emptyValue": "Value can't be empty",
291+
"invalidIdentifier": "Value should start with a letter or _ and contain only letters, digits and _"
291292
}
292293
},
293294
"map": {

0 commit comments

Comments
 (0)