Skip to content

Commit

Permalink
made all monaco instances share one iframe
Browse files Browse the repository at this point in the history
needed to break out of the shadow dom so an iframe was needed, but previously each file had its own iframe, which made modelling a filesystem harder, so now there's one iframe that manages all editors
  • Loading branch information
Mudloop committed Nov 9, 2024
1 parent d473f99 commit c6d9f6e
Show file tree
Hide file tree
Showing 26 changed files with 689 additions and 658 deletions.
4 changes: 2 additions & 2 deletions builders/generated/source-transformer.worker.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions builders/generated/source-transformer.worker.js.map

Large diffs are not rendered by default.

634 changes: 291 additions & 343 deletions docs/bundle/js/index.js

Large diffs are not rendered by default.

41 changes: 19 additions & 22 deletions docs/bundle/js/index.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/bundle/js/monaco.js

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions docs/bundle/js/monaco.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/bundle/js/previews.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/bundle/js/previews.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/service.worker.js

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions playground/src/components/FileEditorBase.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FileContents, MagicFile, Trigger } from "@cmajor-playground/utilities";
import { LitElement, PropertyValues, css } from "lit";
import { LitElement, css } from "lit";
import { COMMON_STYLES } from "./common-styles";

export abstract class FileEditorBase extends LitElement {
Expand All @@ -20,7 +20,7 @@ export abstract class FileEditorBase extends LitElement {
constructor(public file: MagicFile) {
super();
file.onChange.add(this.fileChanged);
file.onDelete.add(this.fileDeleted);
// file.onDelete.add(this.fileDeleted);
this.addEventListener('keydown', async (e: KeyboardEvent) => {
await this.keydownHandler(e);
});
Expand All @@ -36,9 +36,6 @@ export abstract class FileEditorBase extends LitElement {
}
}
}
private fileDeleted = () => {
// this.playground.close(editor);
}
protected keydownHandler = async (e: KeyboardEvent) => {
if (e.key === 's' && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
Expand Down Expand Up @@ -67,6 +64,6 @@ export abstract class FileEditorBase extends LitElement {
dispose(): void {
this.changeTrigger.dispose();
this.file.onChange.remove(this.fileChanged);
this.file.onDelete.remove(this.fileDeleted);
// this.file.onDelete.remove(this.fileDeleted);
}
}
2 changes: 2 additions & 0 deletions playground/src/components/Header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ import { ContextManager } from '@cmajor-playground/utilities';
:host(:not([size="lg"])) #split-right { display: none; }
:host([size="lg"]) #play { display: none; }
:host([size="lg"]) #edit { display: none; }
:host([layout="vertical"]) #split-bottom { opacity: 1; }
:host(:not([layout="vertical"])) #split-right { opacity: 1; }
button {
align-self: center;
padding: 4px 8px;
Expand Down
12 changes: 6 additions & 6 deletions playground/src/components/Icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { customElement, property } from "lit/decorators";
import { loadIcons } from "../macros/loadIcons" with {type: 'macro'};
import { unsafeHTML } from 'lit/directives/unsafe-html';
import { COMMON_STYLES } from "./common-styles";
import { MonacoEditor } from './MonacoEditor';
// import { MonacoEditor } from './MonacoEditor';
import { mtype } from "../mtype";
const icons = loadIcons('../../assets/file-icons', '../../assets/icons', '../../assets/icons/tabler-icons');
export class IconRegistry {
Expand Down Expand Up @@ -71,11 +71,11 @@ export class IconRegistry {
this.removeAttribute('currentColors');
return IconRegistry.getIcon(ext);
}
const lang = MonacoEditor.getLanguage(ext!);
if (lang && IconRegistry.getIcon(lang)) {
this.removeAttribute('currentColors');
return IconRegistry.getIcon(lang);
}
// const lang = MonacoEditor.getLanguage(ext!);
// if (lang && IconRegistry.getIcon(lang)) {
// this.removeAttribute('currentColors');
// return IconRegistry.getIcon(lang);
// }

const mime = mtype(this.path!);
this.setAttribute('currentColors', '');
Expand Down
45 changes: 45 additions & 0 deletions playground/src/components/MonacoContainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { css, html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators.js";
import { Project } from "../state";
@customElement("cmaj-monaco-container") export class MonacoContainer extends LitElement {
@property({ type: String }) focusedFileId?: string;
@property({ type: Object }) project!: Project;
static styles = css`
:host {
display: block;
flex:1;
height: 100%;
width: 100%;
border-top: none;
background-color: #232627;
}
iframe {
width: 100%;
height: 100%;
border: none;
}
`;
iframe!: HTMLIFrameElement;
iframeInitialized = false;
protected firstUpdated(_changedProperties: PropertyValues) {
super.firstUpdated(_changedProperties);
const iframe = this.iframe = this.shadowRoot!.querySelector('iframe')!;
iframe.onload = this.setupIframe;
iframe.src = './monaco.html';
}
protected updated(_changedProperties: PropertyValues) {
if (!this.iframeInitialized) return;
}



setupIframe = async () => {
const iframe = this.iframe;
this.iframeInitialized = false;
await new Promise<void>(resolve => iframe.contentWindow!.addEventListener('message', (e) => e.data == 'editorReady' && resolve()));
const connection: any = (this.iframe.contentWindow as any).connection;
connection.init(this.project);
this.iframeInitialized = true;
}
render = () => html`<iframe></iframe>`
}
106 changes: 54 additions & 52 deletions playground/src/components/MonacoEditor.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
import { css, html, render, unsafeCSS } from "lit";
import { customElement } from "lit/decorators.js";
import monaco from '@cmajor-playground/bunaco';
import monacoCSS from "@cmajor-playground/bunaco/dist/monaco.css" with { type: 'text' };
import { unsafeHTML } from "lit/directives/unsafe-html";
import { FileEditorBase } from "./FileEditorBase";
@customElement("cmaj-monaco-editor") export class MonacoEditor extends FileEditorBase {

static getLanguage = (extension?: string) => (monaco.languages.getLanguages().find(lang => lang.extensions?.includes('.' + extension) || lang.extensions?.includes(extension!)))?.id
static styles = css`
${FileEditorBase.styles}
${unsafeCSS(monacoCSS)}
:host {
overflow: hidden;
background-color: #232627;
position: relative;
height: 100%;
width: 100%;
}
#editor {
position: absolute;
inset: 6px;
display: none;
}
#editor::after {
content: '';
position: absolute;
inset: 0;
// import { css, html, PropertyValues, render, unsafeCSS } from "lit";
// import { customElement, property } from "lit/decorators.js";
// import monaco from '@cmajor-playground/bunaco';
// import monacoCSS from "@cmajor-playground/bunaco/dist/monaco.css" with { type: 'text' };
// import { unsafeHTML } from "lit/directives/unsafe-html";
// import { FileEditorBase } from "./FileEditorBase";
// @customElement("cmaj-monaco-editor") export class MonacoEditor extends FileEditorBase {
// static getLanguage = (extension?: string) => (monaco.languages.getLanguages().find(lang => lang.extensions?.includes('.' + extension) || lang.extensions?.includes(extension!)))?.id
// static styles = css`
// ${FileEditorBase.styles}
// ${unsafeCSS(monacoCSS)}
// :host {
// overflow: hidden;
// background-color: #232627;
// position: relative;
// height: 100%;
// width: 100%;
// }
// #editor {
// position: absolute;
// inset: 6px;
// display: none;
// }
// #editor::after {
// content: '';
// position: absolute;
// inset: 0;

pointer-events: none;
}
iframe {
width: 100%;
height: 100%;
border: none;
}
`;
protected async onFirstContentLoad() {
this.setAttribute('tabindex', '0');
const iframe = this.shadowRoot!.querySelector('iframe')!;
iframe.src = './monaco.html';
await new Promise(resolve => iframe.onload = resolve);
await new Promise<void>(resolve => iframe.contentWindow!.addEventListener('message', (e) => {
if (e.data == 'editorReady') resolve();
}));
// pointer-events: none;
// }
// iframe {
// width: 100%;
// height: 100%;
// border: none;
// }
// `;
// protected async onFirstContentLoad() {
// this.setAttribute('tabindex', '0');
// const iframe = this.shadowRoot!.querySelector('iframe')!;
// iframe.src = './monaco.html';
// await new Promise(resolve => iframe.onload = resolve);
// await new Promise<void>(resolve => iframe.contentWindow!.addEventListener('message', (e) => {
// if (e.data == 'editorReady') resolve();
// }));

(iframe.contentWindow as any).init(this.file, (content: string) => this.setEditorContent(content));
iframe.contentDocument!.addEventListener('keydown', this.keydownHandler)
}
onDispose = () => (this.shadowRoot!.querySelector('iframe')!).src = '';
render = () => html`<iframe></iframe><div id="editor" class="editor"></div>`
onContentUpdate = () => ((this.shadowRoot!.querySelector('iframe')!).contentWindow as any).setContent(this.editorContent as string ?? '');
}
// (iframe.contentWindow as any).init(this.file, (content: string) => this.setEditorContent(content));
// iframe.contentDocument!.addEventListener('keydown', this.keydownHandler)
// }
// protected updated(_changedProperties: PropertyValues): void {
// console.log('updated', _changedProperties);
// }
// onDispose = () => (this.shadowRoot!.querySelector('iframe')!).src = '';
// render = () => html`<iframe></iframe><div id="editor" class="editor"></div>`
// onContentUpdate = () => ((this.shadowRoot!.querySelector('iframe')!).contentWindow as any).setContent(this.editorContent as string ?? '');
// }

render(html`<style>${unsafeHTML(monacoCSS)}</style>`, document.body);
// render(html`<style>${unsafeHTML(monacoCSS)}</style>`, document.body);
47 changes: 17 additions & 30 deletions playground/src/components/Playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
import { LitElement, PropertyValues, css, html } from "lit";
import { customElement, property } from "lit/decorators";
import { Project } from '../state/Project';
import { FileEditorBase } from './FileEditorBase';
import { COMMON_STYLES } from './common-styles';
import { keyed } from 'lit/directives/keyed';
import { Modals } from './Modals';
import { ContextManager, Trigger } from '@cmajor-playground/utilities';
import { App, examples, ProjectInfo, ZipLoader } from '../state';
import { App, EditorFile, examples, ProjectInfo, ZipLoader } from '../state';
export enum Layout { Horizontal = 'horizontal', Vertical = 'vertical' }
import { FaustBuilder, CmajorBuilder } from '@cmajor-playground/builders';

Expand Down Expand Up @@ -45,9 +44,6 @@ await App.init({
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 12px;
}
dialog {
color: inherit;
}
* {
box-sizing: border-box;
user-select: none;
Expand All @@ -57,11 +53,6 @@ await App.init({
:host([layout="vertical"]) #split-bottom { opacity: 1; }
:host(:not([layout="vertical"])) #split-right { opacity: 1; }
:host([size="sm"]) #main-splitter { display: none; }
:host([size="md"][preview-mode]) #main-splitter { display: none; }
:host(:not([size="lg"])) #content-splitter { display: none; }
Expand All @@ -81,7 +72,6 @@ await App.init({
.none {
background-color: #191b1b;
display: flex;
display: none;
flex: 1;
justify-content: center;
align-items: center;
Expand Down Expand Up @@ -161,17 +151,6 @@ await App.init({
display: none;
}
.gutter {
width: 5px;
position: relative;
}
.gutter::after {
content: '';
inset: 1px;
opacity: 0;
background-color: #e2b461;
position: absolute;
}
#content {
flex: 1;
display: flex;
Expand Down Expand Up @@ -210,6 +189,11 @@ await App.init({
ui-icon {
cursor: pointer;
}
// iframe {
// width: 100%;
// height: 100%;
// border: none;
// }
`;
hideProjectPanel: boolean = false;
hideKeyboard: boolean = false;
Expand Down Expand Up @@ -291,19 +275,22 @@ await App.init({
</cmaj-sidebar>
<flex-splitter id="main-splitter" attach="prev"></flex-splitter>
<div id="content">
<cmaj-header size=${this.size} .previewMode=${this.previewMode} .embedded=${this.embedded} .enlarged=${this.enlarged} .playground=${this}></cmaj-header>
<cmaj-header size=${this.size} layout=${this.layout} .previewMode=${this.previewMode} .embedded=${this.embedded} .enlarged=${this.enlarged} .playground=${this}></cmaj-header>
<div id="content-split">
<div id="editors" style="overflow: hidden;">
<div class="none">Open a file to start coding</div>
${this.project!.editors}
</div>
<flex-splitter id="content-splitter" attach="next"></flex-splitter>
<div id="preview" style="display: flex; overflow: hidden;">${keyed(this.project!.info.id, html`<cmaj-products .hideKeyboard=${this.hideKeyboard} position=${this.layout == Layout.Vertical ? 'bottom' : 'right'} .buildManager=${this.project!.buildManager}></cmaj-products>`)}</div>
${keyed(this.project!.info.id, html`
<div id="editors" style="overflow: hidden;">
<div class="none ${this.project?.focusedFile ? 'hidden' : ''}">Open a file to start coding</div>
<cmaj-monaco-container .project=${this.project} .focusedFileId=${this.project?.focusedFile?.file.id} class="${this.project?.focusedFile?.useMonaco ? '' : 'hidden'}"></cmaj-monaco-container>
${!this.project?.focusedFile || this.project?.focusedFile?.useMonaco ? '' : html`123`}
</div>
<flex-splitter id="content-splitter" attach="next"></flex-splitter>
<div id="preview" style="display: flex; overflow: hidden;"><cmaj-products .hideKeyboard=${this.hideKeyboard} position=${this.layout == Layout.Vertical ? 'bottom' : 'right'} .buildManager=${this.project!.buildManager}></cmaj-products></div>
`)}
</div>
</div>
`;
closeProject = () => this.loadProject();
close = async (editor: FileEditorBase) => (await this.project?.closeFile(editor.file.id)) && this.requestUpdate();
close = async (editor: EditorFile) => (await this.project?.closeFile(editor.file.id)) && this.requestUpdate();
toggleMute() {
ContextManager.toggleMute();
this.requestUpdate();
Expand Down
Loading

0 comments on commit c6d9f6e

Please sign in to comment.