Skip to content

Commit

Permalink
perf(monaco): make sure monaco is loaded only once (#67)
Browse files Browse the repository at this point in the history
* perf(monaco): make sure monaco is loaded only once

* chore(): add comments in code and clear interval

* feat(): create utility classes for monaco
  • Loading branch information
Ed Morales authored Jun 11, 2019
1 parent 988260d commit 7df5d9d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 42 deletions.
7 changes: 7 additions & 0 deletions src/platform/code-editor/code-editor.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@
left: 0;
right: 0;
}
}

::ng-deep {
// hide this part of monaco so it doesnt add height
.monaco-aria-container {
display: none;
}
}
69 changes: 27 additions & 42 deletions src/platform/code-editor/code-editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ import { Observable, Subject } from 'rxjs';
import { fromEvent, merge, timer } from 'rxjs';
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';

import { waitUntilMonacoReady } from './code-editor.utils';

const noop: any = () => {
// empty method
};

// counter for ids to allow for multiple editors on one page
let uniqueCounter: number = 0;
let loadedMonaco: boolean = false;
let loadPromise: Promise<void>;
// declare all the built in electron objects
declare const electron: any;
declare const monaco: any;
declare const require: any;
declare const process: any;

@Component({
selector: 'td-code-editor',
Expand Down Expand Up @@ -659,39 +657,33 @@ export class TdCodeEditorComponent implements OnInit, AfterViewInit, ControlValu
*/
ngAfterViewInit(): void {
if (!this._isElectronApp) {
if (loadedMonaco) {
// Wait until monaco editor is available
this.waitForMonaco().then(() => {
this.initMonaco();
});
waitUntilMonacoReady().pipe(
takeUntil(this._destroy),
).subscribe(() => {
this.initMonaco();
});
// check if the script tag has been created in case another code component has done this already
if (!document.getElementById('monaco-loader-script')) {
let onGotAmdLoader: any = () => {
// Load monaco
(<any>window).require.config({ paths: { 'vs': 'assets/monaco/vs' } });
(<any>window).require(['vs/editor/editor.main'], () => {
// TODO
});
};

// Load AMD loader if necessary
if (!(<any>window).require) {
let loaderScript: HTMLScriptElement = document.createElement('script');
loaderScript.id = 'monaco-loader-script';
loaderScript.type = 'text/javascript';
loaderScript.src = 'assets/monaco/vs/loader.js';
loaderScript.addEventListener('load', onGotAmdLoader);
document.body.appendChild(loaderScript);
} else {
loadedMonaco = true;
loadPromise = new Promise<void>((resolve: any) => {
if (typeof((<any>window).monaco) === 'object') {
resolve();
return;
}
let onGotAmdLoader: any = () => {
// Load monaco
(<any>window).require.config({ paths: { 'vs': 'assets/monaco/vs' } });
(<any>window).require(['vs/editor/editor.main'], () => {
this.initMonaco();
resolve();
});
};

// Load AMD loader if necessary
if (!(<any>window).require) {
let loaderScript: HTMLScriptElement = document.createElement('script');
loaderScript.type = 'text/javascript';
loaderScript.src = 'assets/monaco/vs/loader.js';
loaderScript.addEventListener('load', onGotAmdLoader);
document.body.appendChild(loaderScript);
} else {
onGotAmdLoader();
}
});
onGotAmdLoader();
}
}
}
merge(
fromEvent(window, 'resize').pipe(
Expand Down Expand Up @@ -727,13 +719,6 @@ export class TdCodeEditorComponent implements OnInit, AfterViewInit, ControlValu
this._destroy.unsubscribe();
}

/**
* waitForMonaco method Returns promise that will be fulfilled when monaco is available
*/
waitForMonaco(): Promise<void> {
return loadPromise;
}

/**
* showFullScreenEditor request for full screen of Code Editor based on its browser type.
*/
Expand Down
23 changes: 23 additions & 0 deletions src/platform/code-editor/code-editor.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Subject, Observable } from 'rxjs';

/**
* Waits until monaco has been loaded so we can reference its global object.
*/
export function waitUntilMonacoReady(): Observable<void> {
let monacoReady$: Subject<void> = new Subject<void>();

// create interval to check if monaco has been loaded
let interval: any = setInterval(() => {
if (isMonacoLoaded()) {
// clear interval when monaco has been loaded
clearInterval(interval);
monacoReady$.next();
monacoReady$.complete();
}
}, 100);
return monacoReady$.asObservable();
}

export function isMonacoLoaded(): boolean {
return typeof((<any>window).monaco) === 'object';
}
1 change: 1 addition & 0 deletions src/platform/code-editor/public-api.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { TdCodeEditorComponent } from './code-editor.component';
export { CovalentCodeEditorModule } from './code-editor.module';
export * from './code-editor.utils';

0 comments on commit 7df5d9d

Please sign in to comment.