Skip to content

Commit

Permalink
feat(angular): add angular wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
ls-infra committed Oct 10, 2024
1 parent 0a7026f commit ba0768e
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 18 deletions.
12 changes: 10 additions & 2 deletions verify/angular/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
<h2>Monaco Language Client Angular Client Example</h2>
<h2>Monaco Language Client Angular Client Two way data binding Example</h2>
<div>
<div id="monaco-editor-root" class="monaco-editor"></div>
@if(wrapperConfig) {
<monaco-angular-wrapper
[wrapperConfig]="wrapperConfig"
(onTextChanged)="onTextChanged($event)"
></monaco-angular-wrapper>

}

{{ codeText() }}
</div>
32 changes: 18 additions & 14 deletions verify/angular/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,34 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */

import { AfterViewInit, Component } from '@angular/core';
import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
import { AfterViewInit, Component, signal } from '@angular/core';
import { WrapperConfig } from 'monaco-editor-wrapper';
import { MonacoAngularWrapperComponent } from '../monaco-angular-wrapper.component';
import { buildJsonClientUserConfig } from 'monaco-languageclient-examples/json-client';

import '@codingame/monaco-vscode-groovy-default-extension';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
standalone: true
standalone: true,
imports: [MonacoAngularWrapperComponent],
})
export class MonacoEditorComponent implements AfterViewInit {
export class AppComponent implements AfterViewInit {
wrapperConfig: WrapperConfig | undefined;
title = 'angular-client';
initDone = false;

async ngAfterViewInit(): Promise<void> {
const wrapper = new MonacoEditorLanguageClientWrapper();
readonly codeText = signal('');


Check failure on line 24 in verify/angular/src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

More than 1 blank line not allowed
async ngAfterViewInit(): Promise<void> {
const config = buildJsonClientUserConfig({
htmlContainer: document.getElementById('monaco-editor-root')!
htmlContainer: document.getElementById('monaco-editor-root')!,
});
try {
await wrapper.initAndStart(config);
} catch (e) {
console.error(e);
}
this.wrapperConfig = config;
}

onTextChanged(text: string) {
this.codeText.set(text);
}
}

4 changes: 2 additions & 2 deletions verify/angular/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
* ------------------------------------------------------------------------------------------ */

import { bootstrapApplication } from '@angular/platform-browser';
import { MonacoEditorComponent } from './app/app.component';
bootstrapApplication(MonacoEditorComponent);
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent);
128 changes: 128 additions & 0 deletions verify/angular/src/monaco-angular-wrapper.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {

Check failure on line 1 in verify/angular/src/monaco-angular-wrapper.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

missing header
AfterViewInit,
Component,
EventEmitter,
Input,
OnDestroy,
Output,
} from '@angular/core';


Check failure on line 10 in verify/angular/src/monaco-angular-wrapper.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

More than 1 blank line not allowed
import * as monaco from 'monaco-editor';
import {
MonacoEditorLanguageClientWrapper,
WrapperConfig,
} from 'monaco-editor-wrapper';

@Component({
standalone: true,
selector: 'monaco-angular-wrapper',
template: `
<div>
<div id='monaco-editor-root' class='monaco-editor'></div>
</div>
`,
styles: `
.monaco-editor {
height: 50vh;
}
`,
})
export class MonacoAngularWrapperComponent implements AfterViewInit, OnDestroy {
@Output() onTextChanged = new EventEmitter<string>();
@Input() wrapperConfig: WrapperConfig;
title = 'angluar-lang-client';
private wrapper: MonacoEditorLanguageClientWrapper =
new MonacoEditorLanguageClientWrapper();
private containerElement?: HTMLDivElement;
private _subscription: monaco.IDisposable | null = null;
private isRestarting?: Promise<void>;
private started: (value: void | PromiseLike<void>) => void;

async ngAfterViewInit(): Promise<void> {

this.containerElement = document.getElementById(
'monaco-editor-root'
) as HTMLDivElement;
// await this.handleReinit();

Check failure on line 47 in verify/angular/src/monaco-angular-wrapper.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

Expected indentation of 8 spaces but found 5
try {
await this.wrapper.initAndStart(this.wrapperConfig);
} catch (e) {
console.error(e);
}
}

protected async handleReinit() {
await this.destroyMonaco();
await this.initMonaco();
await this.startMonaco();
}

protected async destroyMonaco(): Promise<void> {
if (this.wrapper) {

Check failure on line 62 in verify/angular/src/monaco-angular-wrapper.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

Unexpected object value in conditional. The condition is always true

Check failure on line 62 in verify/angular/src/monaco-angular-wrapper.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

Unnecessary conditional, value is always truthy
if (this.isRestarting) {
await this.isRestarting;
}
try {
await this.wrapper.dispose();
} catch {
// The language client may throw an error during disposal.
// This should not prevent us from continue working.
}
}
if (this._subscription) {
this._subscription.dispose();
}
}

async ngOnDestroy() {
this.destroyMonaco();
}

protected async initMonaco() {
this.isRestarting = new Promise<void>((resolve) => {
this.started = resolve;
});
await this.wrapper.init(this.wrapperConfig);
}

protected async startMonaco() {
if (this.containerElement) {
// exceptions are forwarded to onError callback or the exception is thrown
try {
await this.wrapper.start();
} catch (e) {}

Check failure on line 94 in verify/angular/src/monaco-angular-wrapper.component.ts

View workflow job for this annotation

GitHub Actions / monaco-languageclient

Empty block statement
this.started();
this.isRestarting = undefined;

this.handleOnTextChanged();
}
}

handleOnTextChanged() {
const textModels = this.wrapper.getTextModels();
if (textModels) {
const verifyModelContent = () => {
const text = textModels.text?.getValue() ?? '';
const textOriginal = textModels.textOriginal?.getValue() ?? '';
const codeResources =
this.wrapperConfig.editorAppConfig.codeResources;
const dirty = text !== codeResources?.main?.text;
const dirtyOriginal =
textOriginal !== codeResources?.original?.text;
this.onTextChanged.emit(text);
console.log('dirty , dirtyOriginal', dirty, dirtyOriginal);
};

const newSubscriptions: monaco.IDisposable[] = [];

if (textModels.text) {
newSubscriptions.push(
textModels.text.onDidChangeContent(() => {
verifyModelContent();
})
);
}
}
}
}

0 comments on commit ba0768e

Please sign in to comment.