Skip to content

Commit

Permalink
Merge pull request #2 from IPdotSetAF/1-code-area
Browse files Browse the repository at this point in the history
1 code area
  • Loading branch information
IPdotSetAF authored Oct 27, 2024
2 parents d43ff87 + 5458f38 commit 01a4540
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 91 deletions.
12 changes: 10 additions & 2 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
},
"configurations": {
"production": {
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
},
"budgets": [
{
"type": "initial",
Expand All @@ -49,7 +57,7 @@
{
"type": "anyComponentStyle",
"maximumWarning": "2kB",
"maximumError": "4kB"
"maximumError": "10kB"
}
],
"outputHashing": "all"
Expand Down Expand Up @@ -100,4 +108,4 @@
}
}
}
}
}
22 changes: 6 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3",
"express": "^4.18.2",
"prismjs": "^1.29.0",
"prism-code-editor": "^4.0.0-beta.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
Expand All @@ -37,7 +37,6 @@
"@types/express": "^4.17.17",
"@types/jasmine": "~5.1.0",
"@types/node": "^18.18.0",
"@types/prismjs": "^1.26.4",
"jasmine-core": "~5.2.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
Expand Down
10 changes: 4 additions & 6 deletions src/app/code-area/code-area.component.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
@import "../../../node_modules/prismjs/themes/prism-dark.min.css";

:host.dark {
background: #333;
color: #FFF;
}
@import '../../../node_modules/prism-code-editor/dist/layout.css';
@import '../../../node_modules/prism-code-editor/dist/themes/prism.css';
@import '../../../node_modules/prism-code-editor/dist/themes/github-dark.css';
@import '../../../node_modules/prism-code-editor/dist/copy.css';
110 changes: 80 additions & 30 deletions src/app/code-area/code-area.component.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,94 @@
import { AfterViewInit, Component, ElementRef, HostListener, input, Input } from '@angular/core';
import Prism from 'prismjs';
import { debounceTime, Subject, takeLast, tap } from 'rxjs';
import {
AfterViewInit,
Component,
ElementRef,
Inject,
Input,
input,
model,
OnChanges,
PLATFORM_ID,
SimpleChanges,
ViewChild,
ViewEncapsulation,
} from "@angular/core";
import { isPlatformBrowser } from "@angular/common";
import { createEditor, PrismEditor } from "prism-code-editor";
import { matchBrackets } from "prism-code-editor/match-brackets";
import { highlightBracketPairs } from "prism-code-editor/highlight-brackets";
import { editHistory } from "prism-code-editor/commands";
import { copyButton } from "prism-code-editor/copy-button";
import "prism-code-editor/prism/languages/json";
import "prism-code-editor/prism/languages/yaml";
import "prism-code-editor/prism/languages/toml";
import "prism-code-editor/prism/languages/java";
import "prism-code-editor/prism/languages/xml";
import "prism-code-editor/prism/languages/csharp";
import "prism-code-editor/prism/languages/typescript";

@Component({
selector: 'code-area, [code-area]',
selector: 'code-area',
standalone: true,
imports: [],
template: '<ng-content></ng-content>',
styleUrl: './code-area.component.css'
template: '<div style="display: grid; {{innerStyle}}" class="{{innerClass}}" #editorContainer></div>',
styleUrl: './code-area.component.css',
encapsulation: ViewEncapsulation.ShadowDom
})
export class CodeAreaComponent implements AfterViewInit {
@Input()
code!: string;
export class CodeAreaComponent implements AfterViewInit, OnChanges {
code = model<string>("");
language = input<string>("typescript");
readonly = input<boolean, string>(false, {
transform: (value: string) => value == "true",
});
@Input() innerStyle!: string;
@Input() innerClass!: string;
editor: PrismEditor | undefined = undefined;

@Input()
language = 'javascript';
@ViewChild("editorContainer") editorContainer!: ElementRef;

constructor(private el: ElementRef) { }
isBrowser = false;
constructor(@Inject(PLATFORM_ID) private platformId: any) {
this.isBrowser = isPlatformBrowser(this.platformId);
}

ngAfterViewInit() {
this.highlight(this.code || this.el.nativeElement.innerText)
ngAfterViewInit(): void {
if (!this.isBrowser)
return;

this.inputDebouncer.pipe(
debounceTime(500),
tap(value => this.highlight(value)),
takeLast(1),
).subscribe();
if (this.editorContainer.nativeElement) {
this.editor = this.initEditor();
}
}

private inputDebouncer = new Subject<string>();

@HostListener("input")
protected onInput(){
this.inputDebouncer.next(this.el.nativeElement.innerText);

ngOnChanges(changes: SimpleChanges): void {
if (changes["code"].previousValue !== changes["code"].currentValue) {
this.editor?.setOptions({ value: changes["code"].currentValue });
}
}

private highlight(code: string){
const grammar = Prism.languages[this.language];
const html = Prism.highlight(code, grammar, this.language);
this.el.nativeElement.innerHTML = html;
console.log(code);
initEditor(): PrismEditor {
const editor = createEditor(this.editorContainer.nativeElement, {
value: this.code(),
language: this.language(),
lineNumbers: true,
wordWrap: false,
readOnly: this.readonly(),

onUpdate: (code: string) => {
this.code.set(code);
},
});
editor.addExtensions(
copyButton(),
matchBrackets(true),
highlightBracketPairs(),
editHistory(),
);

this.code.subscribe(() => {
this.editor?.update();
});

return editor;
}
}
14 changes: 7 additions & 7 deletions src/app/cs2ts/cs2ts.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ <h2>C# to TS Converter</h2>
<div class="row">
<div class="col-md-6">
<label for="csharp-code" class="form-label">C# class fields:</label>
<code>
<textarea #csCode class="form-control" id="csharp-code" rows="16" code-area language="clike" (input)="onInput()"
[(ngModel)]="csModel" [placeholder]="placeholder1"></textarea>
</code>
<div class="code-border" >
<code-area innerStyle="min-height:500px;" [(code)]="csCode" (codeChange)="inputDebouncer.next(csCode)"
language="csharp" />
</div>
<br />
</div>
<div class="col-md-6">
<label for="ts-code" class="form-label">TS interface fields:</label>
<code>
<textarea #tsCode [@valueChangeAnim]="status" class="form-control" id="ts-code" rows="16" disabled="true" [ngModel]="tsModel" [placeholder]="placeholder2"></textarea>
</code>
<div class="code-border" [@valueChangeAnim]="status">
<code-area innerStyle="min-height:500px;" [(code)]="tsCode" language="typescript" readonly="true" />
</div>
<br />
</div>
</div>
Expand Down
40 changes: 13 additions & 27 deletions src/app/cs2ts/cs2ts.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,28 @@ import { Meta } from '@angular/platform-browser';
templateUrl: './cs2ts.component.html',
animations: [
trigger('valueChangeAnim', [
state('*', style({ "border-width": "3px" })),
transition('* <=> *', [
animate('0.1s ease-out', style({ "border-color": "var(--bs-success)" })),
animate('0.1s ease-in', style({ "border-color": "none" }))
animate('0.07s ease-out', style({ "border-color": "limegreen" })),
animate('0.07s ease-in', style({ "border-color": "var(--bs-border-color)" }))
]),
])
]
],
styles: `
.code-border{
border: 3px solid var(--bs-border-color);
}
`
})
export class Cs2tsComponent implements AfterContentInit {
@ViewChild("csCode", { read: ElementRef })
protected csCode!: ElementRef<HTMLInputElement>;
@ViewChild("tsCode", { read: ElementRef })
protected tsCode!: ElementRef<HTMLInputElement>;

protected placeholder1: string = `public class a : b {
protected csCode: string = `public class a : b {
public int x1 { get; set; }
public float? x2 { get; set; }
public string x3 { get; set; }
public bool[] x8 { get; set; }
public long[] x9 { get; set; }
public IEnumerable<string> x10 { get; set; }
}`;
protected placeholder2!: string;

protected csModel: string = "";
protected tsModel !: string;
protected tsCode !: string;
protected status: boolean = false;

protected inputDebouncer = new Subject<string>();
Expand All @@ -47,8 +43,6 @@ export class Cs2tsComponent implements AfterContentInit {
{ name: "description", content: "Converts C# model to TS model, converts fields, types, arrays and generics." },
{ name: "keywords", content: "C#, TS, CSharp, TypeScript, script, type, generic, array, converter, model, DTO, DataTransferObject, POCO, fields, string, number, int, class, code, language, long, float, boolean, bool" },
]);

this.placeholder2 = Cs2tsComponent.convert(this.placeholder1);
}

ngAfterContentInit(): void {
Expand All @@ -58,20 +52,12 @@ export class Cs2tsComponent implements AfterContentInit {
takeLast(1),
).subscribe();

this.convert(this.csModel);
}

protected onInput() {
this.inputDebouncer.next(this.csModel);
this.csCode.nativeElement.style.height = "auto";
this.csCode.nativeElement.style.height = `${this.csCode.nativeElement.scrollHeight + 5}px`;
this.tsCode.nativeElement.style.height = "auto";
this.tsCode.nativeElement.style.height = `${this.csCode.nativeElement.scrollHeight + 5}px`;
this.convert(this.csCode);
}

protected convert(csCode?: string) {
let code = csCode ? csCode : this.csModel;
this.tsModel = Cs2tsComponent.convert(code);
let code = csCode ? csCode : this.csCode;
this.tsCode = Cs2tsComponent.convert(code);
this.status = !this.status;
}

Expand Down
1 change: 1 addition & 0 deletions src/app/header/header.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
height: var(--height);
background-color: #212529b0;
backdrop-filter: blur(2px);
z-index: 2;
}

img {
Expand Down
13 changes: 12 additions & 1 deletion src/app/not-found/not-found.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { NotFoundComponent } from './not-found.component';
import { ActivatedRoute } from '@angular/router';

describe('NotFoundComponent', () => {
let component: NotFoundComponent;
let fixture: ComponentFixture<NotFoundComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [NotFoundComponent]
imports: [NotFoundComponent],
providers: [
{
provide: ActivatedRoute,
useValue: {
snapshot: {
url: ["404"]
}
}
},
]
})
.compileComponents();

Expand Down

0 comments on commit 01a4540

Please sign in to comment.