@dotglitch/ngx-common
Version:
Angular components and utilities that are commonly used.
851 lines (839 loc) • 34.4 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, HostListener, Input, Output, Component } from '@angular/core';
import { debounceTime } from 'rxjs';
import * as path from 'path-browserify';
class DependencyParser {
constructor() {
this.REGEX_NODE_MODULE = /^node:([\w\W\/]+)$/;
}
// https://github.com/lukasbach/monaco-editor-auto-typings/commit/fc046e7d9a2abbb5121ad8ab25195d8c1c277416
parseDependencies(source, parent) {
const importRegex = /import *.+ *from *['"](?<importPath>.+?)['"]/g;
const dynamicImportRegex = /await import ?\(['"](?<importPath>.+?)['"]\)/g;
const cjsRequireRegex = /require *\(['"](?<importPath>.+?)['"]\)/g;
const matches = [
...source.matchAll(importRegex),
...source.matchAll(dynamicImportRegex),
...source.matchAll(cjsRequireRegex)
];
const importPaths = matches.map(match => match.groups?.['importPath']);
const result = importPaths.map(imp => this.resolvePath(imp, parent));
return result;
}
resolvePath(importPath, parent) {
const nodeImport = importPath.match(this.REGEX_NODE_MODULE);
if (nodeImport) {
return {
kind: 'relative-in-package',
packageName: '@types/node',
importPath: `${nodeImport[1]}.d.ts`,
sourcePath: '',
};
}
if (typeof parent === 'string') {
if (importPath.startsWith('.')) {
return {
kind: 'relative',
importPath,
sourcePath: parent,
};
}
else if (importPath.startsWith('@')) {
const segments = importPath.split('/');
return {
kind: 'package',
packageName: `${segments[0]}/${segments[1]}`,
importPath: segments.slice(2).join('/'),
};
}
else {
const segments = importPath.split('/');
return {
kind: 'package',
packageName: segments[0],
importPath: segments.slice(1).join('/'),
};
}
}
else {
switch (parent.kind) {
case 'package':
throw Error('TODO?');
case 'relative':
throw Error('TODO2?');
case 'relative-in-package':
if (importPath.startsWith('.')) {
return {
kind: 'relative-in-package',
packageName: parent.packageName,
sourcePath: path.join(parent.sourcePath, parent.importPath),
importPath: importPath,
};
}
else if (importPath.startsWith('@')) {
const segments = importPath.split('/');
return {
kind: 'package',
packageName: `${segments[0]}/${segments[1]}`,
importPath: segments.slice(2).join('/'),
};
}
else {
const segments = importPath.split('/');
return {
kind: 'package',
packageName: segments[0],
importPath: segments.slice(1).join('/'),
};
}
}
}
return null;
}
}
const invokeUpdate = (progress, options) => {
let textual = `${progress.type}: `;
switch (progress.type) {
case 'CodeChanged':
textual += ``;
break;
case 'ResolveNewImports':
textual += ``;
break;
// case 'DetectedImport':
// textual += `at "${progress.source}" the import "${progress.importPath}" was detected`;
// break;
// case 'CompletedImport':
// textual += `at "${progress.source}" the import "${progress.importPath}" was completed`;
// break;
case 'LookedUpTypeFile':
textual += `"${progress.path}" was ${progress.success ? 'sucessfully' : 'not sucessfully'} looked up`;
break;
case 'AttemptedLookUpFile':
textual += `"${progress.path}" was ${progress.success ? 'sucessfully' : 'not sucessfully'} attempted to looked up`; // What in the hell is this grammar?
break;
case 'LookedUpPackage':
textual += `package.json for package "${progress.package}" was ${progress.success ? 'sucessfully' : 'not sucessfully'} looked up${progress.definitelyTyped ? ' (found in definitely typed repo)' : ''}`;
break;
case 'LoadedFromCache':
textual += `"${progress.importPath}" was loaded from cache`;
break;
case 'StoredToCache':
textual += `"${progress.importPath}" was stored to cache`;
break;
}
if (textual.endsWith(': ')) {
textual = textual.slice(undefined, -2);
}
options.onUpdate?.(progress, textual);
};
class RecursionDepth {
constructor(options, fileRecursionDepth = 0, packageRecursionDepth = 0) {
this.options = options;
this.fileRecursionDepth = fileRecursionDepth;
this.packageRecursionDepth = packageRecursionDepth;
}
nextPackage() {
return new RecursionDepth(this.options, this.fileRecursionDepth, this.packageRecursionDepth + 1);
}
nextFile() {
return new RecursionDepth(this.options, this.fileRecursionDepth + 1, this.packageRecursionDepth);
}
same() {
return new RecursionDepth(this.options, this.fileRecursionDepth, this.packageRecursionDepth);
}
shouldStop() {
return ((this.options.fileRecursionDepth > 0 && this.fileRecursionDepth >= this.options.fileRecursionDepth) ||
(this.options.packageRecursionDepth > 0 && this.packageRecursionDepth >= this.options.packageRecursionDepth));
}
}
const importResourcePathToString = (p) => {
switch (p.kind) {
case 'package':
return path.join(p.packageName, p.importPath ?? '', 'package.json');
case 'relative':
return path.join(p.sourcePath, p.importPath);
case 'relative-in-package':
return path.join(p.packageName, p.sourcePath, p.importPath);
case 'bruteforce':
throw new Error("Not Implemented");
}
};
class UnpkgSourceResolver {
static async resolvePackageJson(packageName, version, subPath) {
return await this.resolveFile(`https://unpkg.com/${packageName}${version ? `@${version}` : ''}${subPath ? `/${subPath}` : ''}/package.json`);
}
static async resolveSourceFile(packageName, version, path) {
return await this.resolveFile(`https://unpkg.com/${packageName}${version ? `@${version}` : ''}/${path}`);
}
static async resolveFile(url) {
const res = await fetch(url, { method: 'GET' });
if (res.ok) {
return await res.text();
}
else if (res.status === 404) {
return '';
}
else {
throw Error(`Error other than 404 while fetching from Unpkg at ${url}`);
}
}
}
class ImportResolver {
constructor(options) {
this.options = options;
this.loadedFiles = [];
this.dependencyParser = new DependencyParser();
this.cache = options.sourceCache;
this.newImportsResolved = false;
this.monaco = options.monaco;
if (options.preloadPackages && options.versions) {
this.versions = options.versions;
for (const [packageName, version] of Object.entries(options.versions)) {
this.resolveImport({
kind: 'package',
packageName: packageName,
importPath: '',
}, new RecursionDepth(this.options)).catch(e => {
console.error(e);
});
}
}
}
wereNewImportsResolved() {
return this.newImportsResolved;
}
resetNewImportsResolved() {
this.newImportsResolved = false;
}
async resolveImportsInFile(source, parent, depth) {
if (depth.shouldStop()) {
return;
}
const imports = this.dependencyParser.parseDependencies(source, parent);
for (const importCall of imports) {
try {
await this.resolveImport(importCall, depth);
}
catch (e) {
if (this.options.onError) {
this.options.onError?.(e.message ?? e);
}
else {
console.error(e);
}
}
}
}
async resolveImport(importResource, depth) {
const hash = this.hashImportResourcePath(importResource);
if (this.loadedFiles.includes(hash)) {
return;
}
this.loadedFiles.push(hash);
console.log("resolveImport", importResource, depth);
// Ignore these package imports as they are well-known to be pointless.
if (importResource.kind == "package" && importResource.packageName == "require")
return null;
switch (importResource.kind) {
case 'package':
const packageRelativeImport = await this.resolveImportFromPackageRoot(importResource);
if (packageRelativeImport) {
return await this.resolveImportInPackage(packageRelativeImport, depth.nextPackage().nextFile());
}
break;
case 'relative':
throw Error('Not implemented yet');
case 'relative-in-package':
return await this.resolveImportInPackage(importResource, depth.nextFile());
case 'bruteforce': {
}
}
}
async resolveImportInPackage(importResource, depth) {
console.log("resolveImportInPackage", importResource, depth);
const contents = await this.loadSourceFileContents(importResource);
if (contents) {
const { source, at } = contents;
this.createModel(source, this.monaco.Uri.parse(this.options.fileRootPath + path.join(`node_modules/${importResource.packageName}`, at)));
await this.resolveImportsInFile(source, {
kind: 'relative-in-package',
packageName: importResource.packageName,
sourcePath: path.dirname(at),
importPath: '',
}, depth);
}
}
async resolveImportFromPackageRoot(importResource) {
console.log("resolveImportFromPackageRoot", importResource);
const failedProgressUpdate = {
type: 'LookedUpPackage',
package: importResource.packageName,
definitelyTyped: false,
success: false,
};
if (this.options.onlySpecifiedPackages) {
if (!this.versions?.[importResource.packageName] && !this.versions?.['@types/' + importResource.packageName]) {
invokeUpdate(failedProgressUpdate, this.options);
return null;
}
}
const doesPkgJsonHasSubpath = importResource.importPath?.length ?? 0 > 0;
let pkgJsonSubpath = doesPkgJsonHasSubpath ? `/${importResource.importPath}` : '';
let pkgJson = await this.resolvePackageJson(importResource.packageName, this.versions?.[importResource.packageName], doesPkgJsonHasSubpath ? importResource.importPath : undefined);
if (!pkgJson && doesPkgJsonHasSubpath) {
pkgJson = await this.resolvePackageJson(importResource.packageName, this.versions?.[importResource.packageName]);
pkgJsonSubpath = '';
}
if (!pkgJson)
return invokeUpdate(failedProgressUpdate, this.options);
const pkg = JSON.parse(pkgJson);
console.log("package meta", pkg);
if (pkg.typings || pkg.types) {
const typings = pkg.typings || pkg.types;
this.createModel(pkgJson, this.monaco.Uri.parse(`${this.options.fileRootPath}node_modules/${importResource.packageName}${pkgJsonSubpath}/package.json`));
invokeUpdate({
type: 'LookedUpPackage',
package: importResource.packageName,
definitelyTyped: false,
success: true,
}, this.options);
this.setVersion(importResource.packageName, pkg.version);
return {
kind: 'relative-in-package',
packageName: importResource.packageName,
sourcePath: '',
importPath: path.join(importResource.importPath ?? '', typings.startsWith('./') ? typings.slice(2) : typings),
};
}
else {
const typingPackageName = `@types/${importResource.packageName.startsWith('@')
? importResource.packageName.slice(1).replace(/\//, '__')
: importResource.packageName}`;
const pkgJsonTypings = await this.resolvePackageJson(typingPackageName, this.versions?.[typingPackageName]);
if (!pkgJsonTypings)
return invokeUpdate(failedProgressUpdate, this.options);
const pkg = JSON.parse(pkgJsonTypings);
if (!pkg.typings && !pkg.types) {
const files = await fetch("https://www.npmjs.com/package/@dt-esa/dynatrace-api-client/v/2.2.6/index", {
method: "get"
}).then(e => e.json());
const typingFiles = Object.entries(files.files).map(([key, val]) => val);
invokeUpdate({
type: 'LookedUpPackage',
package: typingPackageName,
definitelyTyped: true,
success: true,
}, this.options);
return {
kind: 'bruteforce',
packageName: typingPackageName,
typingFiles,
};
return;
// return invokeUpdate(failedProgressUpdate, this.options);
}
const typings = pkg.typings || pkg.types;
this.createModel(pkgJsonTypings, this.monaco.Uri.parse(`${this.options.fileRootPath}node_modules/${typingPackageName}/package.json`));
invokeUpdate({
type: 'LookedUpPackage',
package: typingPackageName,
definitelyTyped: true,
success: true,
}, this.options);
this.setVersion(typingPackageName, pkg.version);
return {
kind: 'relative-in-package',
packageName: typingPackageName,
sourcePath: '',
importPath: path.join(importResource.importPath ?? '', typings.startsWith('./') ? typings.slice(2) : typings),
};
}
}
async loadSourceFileContents(importResource) {
const progressUpdatePath = path.join(importResource.packageName, importResource.sourcePath, importResource.importPath);
const failedProgressUpdate = {
type: 'LookedUpTypeFile',
path: progressUpdatePath,
definitelyTyped: false,
success: false,
};
const pkgName = importResource.packageName;
const version = this.getVersion(importResource.packageName);
let appends = ['.d.ts', '/index.d.ts', '.ts', '.tsx', '/index.ts', '/index.tsx'];
if (appends.map(append => importResource.importPath.endsWith(append)).reduce((a, b) => a || b, false)) {
const source = await this.resolveSourceFile(pkgName, version, path.join(importResource.sourcePath, importResource.importPath));
if (source) {
return { source, at: path.join(importResource.sourcePath, importResource.importPath) };
}
}
else {
for (const append of appends) {
const fullPath = path.join(importResource.sourcePath, importResource.importPath) + append;
const source = await this.resolveSourceFile(pkgName, version, fullPath);
invokeUpdate({
type: 'AttemptedLookUpFile',
path: path.join(pkgName, fullPath),
success: !!source,
}, this.options);
if (source) {
invokeUpdate({
type: 'LookedUpTypeFile',
path: path.join(pkgName, fullPath),
success: true,
}, this.options);
return { source, at: fullPath };
}
}
}
const pkgJson = await this.resolvePackageJson(pkgName, version, path.join(importResource.sourcePath, importResource.importPath));
if (pkgJson) {
const { types } = JSON.parse(pkgJson);
if (types) {
const fullPath = path.join(importResource.sourcePath, importResource.importPath, types);
const source = await this.resolveSourceFile(pkgName, version, fullPath);
if (source) {
invokeUpdate({
type: 'LookedUpTypeFile',
path: path.join(pkgName, fullPath),
success: true,
}, this.options);
return { source, at: fullPath };
}
}
}
invokeUpdate(failedProgressUpdate, this.options);
return null;
}
getVersion(packageName) {
return this.versions?.[packageName];
}
setVersions(versions) {
this.versions = versions;
this.options.onUpdateVersions?.(versions);
// TODO reload packages whose version has changed
}
setVersion(packageName, version) {
this.setVersions({
...this.versions,
[packageName]: version,
});
}
createModel(source, uri) {
uri = uri.with({ path: uri.path.replace('@types/', '') });
if (!this.monaco.editor.getModel(uri)) {
this.monaco.editor.createModel(source, 'typescript', uri);
this.newImportsResolved = true;
}
}
hashImportResourcePath(p) {
return importResourcePathToString(p);
}
async resolvePackageJson(packageName, version, subPath) {
const uri = path.join(packageName + (version ? `@${version}` : ''), subPath ?? '', 'package.json');
let isAvailable = false;
let content = undefined;
if (this.cache.isFileAvailable) {
isAvailable = await this.cache.isFileAvailable(uri);
}
else {
content = await this.cache.getFile(uri);
isAvailable = content !== undefined;
}
if (isAvailable) {
return content ?? (await this.cache.getFile(uri));
}
else {
console.log("recursing resolvePackageJson", packageName, version, subPath);
content = await UnpkgSourceResolver.resolvePackageJson(packageName, version, subPath);
if (content) {
this.cache.storeFile(uri, content);
}
return content;
}
}
async resolveSourceFile(packageName, version, filePath) {
const uri = path.join(packageName + (version ? `@${version}` : ''), filePath);
let isAvailable = false;
let content = undefined;
if (this.cache.isFileAvailable) {
isAvailable = await this.cache.isFileAvailable(uri);
}
else {
content = await this.cache.getFile(uri);
isAvailable = content !== undefined;
}
if (isAvailable) {
invokeUpdate({
type: 'LoadedFromCache',
importPath: uri,
}, this.options);
return content ?? (await this.cache.getFile(uri));
}
else {
content = await UnpkgSourceResolver.resolveSourceFile(packageName, version, filePath);
if (content) {
invokeUpdate({
type: 'StoredToCache',
importPath: uri,
}, this.options);
this.cache.storeFile(uri, content);
}
return content;
}
}
}
class DummySourceCache {
getFile(uri) {
return undefined;
}
async isFileAvailable(uri) {
return false;
}
storeFile(uri, content) {
return undefined;
}
clear() {
return undefined;
}
}
// https://github.com/lukasbach/monaco-editor-auto-typings
class MonacoAutoTypeImporter {
constructor(editor, options) {
this.editor = editor;
this.options = options;
this.disposables = [];
this.importResolver = new ImportResolver(options);
const changeModelDisposable = editor.onDidChangeModelContent(e => {
this.debouncedResolveContents();
});
this.disposables.push(changeModelDisposable);
this.resolveContents();
if (!options.dontAdaptEditorOptions) {
options.monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
...options.monaco.languages.typescript.typescriptDefaults.getCompilerOptions(),
moduleResolution: options.monaco.languages.typescript.ModuleResolutionKind.NodeJs,
allowSyntheticDefaultImports: true,
rootDir: options.fileRootPath,
});
}
}
static async create(editor, options) {
if (options?.shareCache && options.sourceCache && !MonacoAutoTypeImporter.sharedCache) {
MonacoAutoTypeImporter.sharedCache = options.sourceCache;
}
const monacoInstance = options?.monaco ?? window['monaco'];
if (!monacoInstance) {
throw new Error('monacoInstance not found, you can specify the monaco instance via options.monaco');
}
return new MonacoAutoTypeImporter(editor, {
fileRootPath: 'inmemory://model/',
onlySpecifiedPackages: false,
preloadPackages: false,
shareCache: false,
dontAdaptEditorOptions: false,
dontRefreshModelValueAfterResolvement: false,
sourceCache: MonacoAutoTypeImporter.sharedCache ?? new DummySourceCache(),
debounceDuration: 4000,
fileRecursionDepth: 10,
packageRecursionDepth: 3,
...options,
monaco: monacoInstance,
});
}
dispose() {
this.disposables.forEach(d => d.dispose());
}
setVersions(versions) {
this.importResolver.setVersions(versions);
this.options.versions = versions;
}
async clearCache() {
await this.options.sourceCache.clear();
}
debouncedResolveContents() {
if (this.isResolving) {
return;
}
invokeUpdate({ type: 'CodeChanged' }, this.options);
if (this.options.debounceDuration <= 0) {
this.resolveContents();
}
else {
if (this.debounceTimer !== undefined) {
clearTimeout(this.debounceTimer);
}
this.debounceTimer = setTimeout(async () => {
await this.resolveContents();
this.debounceTimer = undefined;
}, this.options.debounceDuration);
}
}
async resolveContents() {
this.isResolving = true;
invokeUpdate({ type: 'ResolveNewImports' }, this.options);
const model = this.editor.getModel();
// This can happen when the editor is disposed before all typings
// are installed.
if (!model) {
throw Error('No model');
}
const content = model.getLinesContent();
try {
await this.importResolver.resolveImportsInFile(content.join('\n'), path.dirname(model.uri.toString()), new RecursionDepth(this.options));
}
catch (e) {
if (this.options.onError) {
this.options.onError(e.message ?? e);
}
else {
throw e;
}
}
if (this.importResolver.wereNewImportsResolved()) {
if (!this.options.dontRefreshModelValueAfterResolvement) {
const currentPosition = this.editor.getPosition();
model.setValue(model.getValue());
if (currentPosition) {
this.editor.setPosition(currentPosition);
}
}
this.importResolver.resetNewImportsResolved();
}
this.isResolving = false;
}
}
let Monaco;
class MonacoEditorComponent {
set code(value) {
if (value == this._code)
return;
if (typeof value != "string")
throw new TypeError("Value must be of type string");
this._code = value;
this.editor?.setValue(this.code);
}
;
get code() { return this._code?.trim(); }
set language(value) {
this._language = {
'ts': "typescript",
'html': 'xml',
'scss': 'css'
}[value] || value || "auto";
}
get language() { return this._language; }
get settings() {
return {
...this.restSettings,
theme: this.theme,
language: this.language,
tabSize: this.tabSize,
readOnly: this.readOnly,
fontFamily: this.fontFamily,
fontSize: this.fontSize,
automaticLayout: this.automaticLayout,
scrollBeyondLastLine: this.scrollBeyondLastLine,
colorDecorators: this.colorDecorators,
folding: this.folding,
scrollBeyondLastColumn: this.scrollBeyondLastColumn,
minimap: this.minimap,
scrollbar: this.scrollbar,
smoothScrolling: this.smoothScrolling,
mouseWheelScrollSensitivity: this.mouseWheelScrollSensitivity,
lineNumbers: this.lineNumbers
};
}
constructor(viewContainer) {
this.viewContainer = viewContainer;
this.isDirty = false;
this.codeChange = new EventEmitter();
this.onCodeType = new EventEmitter();
this.typeDebounce = this.onCodeType.pipe(debounceTime(100));
this.installationLocation = "/lib/monaco/vs";
this.tabSize = 2;
this.readOnly = false;
this.theme = "vs-dark";
this.fontFamily = "Droid Sans Mono";
this.fontSize = 14;
this.automaticLayout = true;
this.colorDecorators = true;
this.folding = true;
this.minimapEnabled = true;
this.minimap = {
enabled: true
};
this.scrollbar = {
alwaysConsumeMouseWheel: false,
// scrollByPage: true
};
this.smoothScrolling = true;
this.mouseWheelScrollSensitivity = 2;
this.scrollBeyondLastLine = false;
this.scrollBeyondLastColumn = 0;
this.lineNumbers = "on";
this.restSettings = {};
this.resize = () => {
this.editor?.layout();
};
this._sub = this.typeDebounce.subscribe(t => {
this.codeChange.next(this._code = this.editor.getValue());
});
}
ngOnInit() {
InstallMonacoUMD(this.installationLocation);
}
ngOnChanges(changes) {
// If we changed anything OTHER than code, reload the editor
if (Object.keys(changes).length > 1 || !changes['code']) {
if (this.editor) {
this.editor?.dispose();
this.createEditor();
}
}
if (changes['theme'])
window['monaco']?.editor.setTheme(this.theme);
}
async ngAfterViewInit() {
await InstallMonacoUMD();
this.createEditor();
}
ngOnDestroy() {
this.editor?.dispose();
this._sub?.unsubscribe();
}
createEditor() {
if (this.customLanguage) {
this.customLanguage.init(window['monaco']);
}
let editor = this.editor = window['monaco'].editor.create(this.viewContainer?.element?.nativeElement, this.settings);
// const autoTypings = await
MonacoAutoTypeImporter.create(editor, {
monaco: Monaco,
});
this.configureLanguageSupport();
if (this.code) {
editor.setValue(this.code);
}
editor.getModel().onDidChangeContent(() => this.onCodeType.emit());
}
configureLanguageSupport() {
}
download() {
const code = this.editor.getValue();
let blob = new Blob([code], { type: 'text/log' });
let elm = document.createElement('a');
let blobURL = URL.createObjectURL(blob);
// Set the data values.
elm.href = blobURL;
elm.download = this.filename;
document.body.appendChild(elm);
elm.click();
document.body.removeChild(elm);
elm.remove();
URL.revokeObjectURL(blobURL);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MonacoEditorComponent, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MonacoEditorComponent, isStandalone: true, selector: "ngx-monaco-editor", inputs: { code: "code", customLanguage: "customLanguage", language: "language", installationLocation: "installationLocation", tabSize: "tabSize", readOnly: "readOnly", theme: "theme", fontFamily: "fontFamily", fontSize: "fontSize", automaticLayout: "automaticLayout", colorDecorators: "colorDecorators", folding: "folding", minimapEnabled: "minimapEnabled", minimap: "minimap", scrollbar: "scrollbar", smoothScrolling: "smoothScrolling", mouseWheelScrollSensitivity: "mouseWheelScrollSensitivity", scrollBeyondLastLine: "scrollBeyondLastLine", scrollBeyondLastColumn: "scrollBeyondLastColumn", lineNumbers: "lineNumbers", restSettings: "restSettings" }, outputs: { codeChange: "codeChange" }, host: { listeners: { "window:resize": "resize($event)" } }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, styles: [":host{display:block;height:100%;max-height:100vh;max-width:100vw}\n"] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MonacoEditorComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-monaco-editor', template: '', standalone: true, styles: [":host{display:block;height:100%;max-height:100vh;max-width:100vw}\n"] }]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }], propDecorators: { code: [{
type: Input
}], codeChange: [{
type: Output
}], customLanguage: [{
type: Input
}], language: [{
type: Input
}], installationLocation: [{
type: Input
}], tabSize: [{
type: Input
}], readOnly: [{
type: Input
}], theme: [{
type: Input
}], fontFamily: [{
type: Input
}], fontSize: [{
type: Input
}], automaticLayout: [{
type: Input
}], colorDecorators: [{
type: Input
}], folding: [{
type: Input
}], minimapEnabled: [{
type: Input
}], minimap: [{
type: Input
}], scrollbar: [{
type: Input
}], smoothScrolling: [{
type: Input
}], mouseWheelScrollSensitivity: [{
type: Input
}], scrollBeyondLastLine: [{
type: Input
}], scrollBeyondLastColumn: [{
type: Input
}], lineNumbers: [{
type: Input
}], restSettings: [{
type: Input
}], resize: [{
type: HostListener,
args: ['window:resize', ['$event']]
}] } });
const InstallMonacoUMD = async (path) => {
if (window['monaco'])
return window['monaco'];
// Prevent duplicate injection
const scriptEls = document.querySelectorAll('body>script[monaco][defer][src]');
// Only perform installation if a path is specified.
if (path && scriptEls.length == 0) {
// Monaco has a UMD loader that requires this
// Merge with any pre-existing global require objects.
if (!window['require'])
window['require'] = {};
if (!window['require']['paths'])
window['require']['paths'] = {};
if (path.endsWith('/'))
path = path.slice(0, -1);
window['require']['paths'].vs = path;
const monacoFiles = [
'loader.js',
'editor/editor.main.nls.js',
'editor/editor.main.js',
];
for (let i = 0; i < monacoFiles.length; i++) {
const script = document.createElement("script");
script.setAttribute("monaco", "");
script.setAttribute("defer", "");
script.setAttribute("src", path + '/' + monacoFiles[i]);
document.body.append(script);
}
}
// Return a promise that will resolve when monaco finishes loading
return await new Promise((res, rej) => {
let count = 0;
let i = window.setInterval(() => {
count++;
if (window['monaco'] != undefined) {
window.clearInterval(i);
res(true);
}
else if (count >= 100) {
window.clearInterval(i);
res(false);
}
}, 100);
});
};
/**
* Generated bundle index. Do not edit.
*/
export { InstallMonacoUMD, MonacoEditorComponent };
//# sourceMappingURL=dotglitch-ngx-common-monaco-editor.mjs.map