diff --git a/website/package.json b/website/package.json index c621280b..79495e7a 100644 --- a/website/package.json +++ b/website/package.json @@ -28,7 +28,8 @@ "react": "^17.0.2", "react-bootstrap": "^2.4.0", "react-dom": "^17.0.2", - "typedoc": "^0.23.26" + "typedoc": "^0.23.26", + "@vscode/web-editors": "./vscode-web-editors.tgz" }, "devDependencies": { "@types/classnames": "^2.3.1", diff --git a/website/src/website/components/Nav.tsx b/website/src/website/components/Nav.tsx index 4541cc01..7cc6c069 100644 --- a/website/src/website/components/Nav.tsx +++ b/website/src/website/components/Nav.tsx @@ -1,4 +1,4 @@ -import React = require("react"); +import * as React from "react"; import { home, playground, docs, monarch } from "../pages/routes"; import { Container, Navbar, Nav, NavDropdown } from "./bootstrap"; diff --git a/website/src/website/components/Page.tsx b/website/src/website/components/Page.tsx index 6f941c95..fc50d6f7 100644 --- a/website/src/website/components/Page.tsx +++ b/website/src/website/components/Page.tsx @@ -1,4 +1,4 @@ -import React = require("react"); +import * as React from "react"; import { PageNav } from "./Nav"; export function Page(props: { children: React.ReactNode }) { diff --git a/website/src/website/components/Select.tsx b/website/src/website/components/Select.tsx index d14897e0..89564d25 100644 --- a/website/src/website/components/Select.tsx +++ b/website/src/website/components/Select.tsx @@ -1,5 +1,5 @@ import { observer } from "mobx-react"; -import React = require("react"); +import * as React from "react"; import { IReference } from "../utils/ref"; import { Form } from "./bootstrap"; diff --git a/website/src/website/monacoEditorVersion.ts b/website/src/website/monacoEditorVersion.ts index 803c4945..1f5b9be7 100644 --- a/website/src/website/monacoEditorVersion.ts +++ b/website/src/website/monacoEditorVersion.ts @@ -3,6 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as packageJson from "monaco-editor/package.json"; +import packageJson from "monaco-editor/package.json"; export const monacoEditorVersion = packageJson.version; diff --git a/website/src/website/pages/App.tsx b/website/src/website/pages/App.tsx index 2537e3ac..e3e15672 100644 --- a/website/src/website/pages/App.tsx +++ b/website/src/website/pages/App.tsx @@ -1,7 +1,7 @@ import { Home } from "./home/Home"; import { PlaygroundPage } from "./playground/PlaygroundPage"; import { docs, home, monarch, playground } from "./routes"; -import React = require("react"); +import * as React from "react"; import { DocsPage } from "./DocsPage"; import { MonarchPage } from "./MonarchPage"; diff --git a/website/src/website/pages/DocsPage.tsx b/website/src/website/pages/DocsPage.tsx index 79eb9e0f..c138e5a5 100644 --- a/website/src/website/pages/DocsPage.tsx +++ b/website/src/website/pages/DocsPage.tsx @@ -5,7 +5,7 @@ import { IHistoryModel, ILocation, } from "../utils/ObservableHistory"; -import React = require("react"); +import * as React from "react"; export class DocsPage extends React.Component implements IHistoryModel { private _lastIFrame: HTMLIFrameElement | null = null; diff --git a/website/src/website/pages/MonarchPage.tsx b/website/src/website/pages/MonarchPage.tsx index 649acfcc..f6ae3343 100644 --- a/website/src/website/pages/MonarchPage.tsx +++ b/website/src/website/pages/MonarchPage.tsx @@ -1,4 +1,4 @@ -import React = require("react"); +import * as React from "react"; import { Page } from "../components/Page"; export class MonarchPage extends React.Component<{}, {}> { diff --git a/website/src/website/pages/home/Home.tsx b/website/src/website/pages/home/Home.tsx index 759a06b2..42124b4b 100644 --- a/website/src/website/pages/home/Home.tsx +++ b/website/src/website/pages/home/Home.tsx @@ -8,7 +8,7 @@ import { ControlledMonacoEditor, } from "../../components/monaco/MonacoEditor"; import { ObservablePromise } from "../../utils/ObservablePromise"; -import React = require("react"); +import * as React from "react"; import { ref } from "../../utils/ref"; import { monacoEditorVersion } from "../../monacoEditorVersion"; diff --git a/website/src/website/pages/playground/LocationModel.ts b/website/src/website/pages/playground/LocationModel.ts index abc96ad1..d2679979 100644 --- a/website/src/website/pages/playground/LocationModel.ts +++ b/website/src/website/pages/playground/LocationModel.ts @@ -38,13 +38,18 @@ export class LocationModel implements IHistoryModel { */ @observable historyId: number = 0; - constructor(private readonly model: PlaygroundModel) { - this.dispose.track( - new HistoryController((initialLocation) => { - this.updateLocation(initialLocation); - return this; - }) - ); + constructor( + private readonly model: PlaygroundModel, + createHistoryController = true + ) { + if (createHistoryController) { + this.dispose.track( + new HistoryController((initialLocation) => { + this.updateLocation(initialLocation); + return this; + }) + ); + } } get location(): ILocation { diff --git a/website/src/website/pages/playground/PlaygroundModel.ts b/website/src/website/pages/playground/PlaygroundModel.ts index 46ea286c..5c33dd4d 100644 --- a/website/src/website/pages/playground/PlaygroundModel.ts +++ b/website/src/website/pages/playground/PlaygroundModel.ts @@ -30,6 +30,7 @@ import { } from "./SettingsModel"; import { BisectModel } from "./BisectModel"; import { LocationModel } from "./LocationModel"; +import { createJsonWebEditorClient, vObj, vString } from "@vscode/web-editors"; export class PlaygroundModel { public readonly dispose = Disposable.fn(); @@ -47,7 +48,25 @@ export class PlaygroundModel { @observable public reloadKey = 0; - public readonly historyModel = new LocationModel(this); + private readonly webEditorClient = createJsonWebEditorClient( + vObj({ + js: vString(), + html: vString(), + css: vString(), + }), + (data) => { + runInAction(() => { + this.html = data.html; + this.js = data.js; + this.css = data.css; + }); + } + ); + + public readonly historyModel = new LocationModel( + this, + this.webEditorClient === undefined + ); public reload(): void { this.reloadKey++; @@ -163,6 +182,17 @@ export class PlaygroundModel { constructor() { let lastState: IPreviewState | undefined = undefined; + this.webEditorClient?.onDidConnect.then(() => { + autorun(() => { + const state = this.playgroundProject; + this.webEditorClient!.updateContent({ + js: state.js, + html: state.html, + css: state.css, + }); + }); + }); + this.dispose.track({ dispose: reaction( () => ({ state: this.state }), diff --git a/website/src/website/pages/playground/SettingsModel.ts b/website/src/website/pages/playground/SettingsModel.ts index 00016c10..36c16566 100644 --- a/website/src/website/pages/playground/SettingsModel.ts +++ b/website/src/website/pages/playground/SettingsModel.ts @@ -42,7 +42,12 @@ export class SettingsModel { } constructor() { - const settingsStr = localStorage.getItem(this.settingsKey); + const settingsStr = ""; + try { + localStorage.getItem(this.settingsKey); + } catch (e) { + console.error("Failed to load settings from localStorage", e); + } if (settingsStr) { this._settings = JSON.parse(settingsStr); } else { @@ -54,7 +59,11 @@ export class SettingsModel { setSettings(settings: Settings): void { const settingsJson = JSON.stringify(toJS(settings)); this._settings = JSON.parse(settingsJson); - localStorage.setItem(this.settingsKey, settingsJson); + try { + localStorage.setItem(this.settingsKey, settingsJson); + } catch (e) { + console.error("Failed to save settings to localStorage", e); + } } } diff --git a/website/src/website/pages/playground/utils.ts b/website/src/website/pages/playground/utils.ts index 29d9fd10..15d1b29c 100644 --- a/website/src/website/pages/playground/utils.ts +++ b/website/src/website/pages/playground/utils.ts @@ -1,4 +1,3 @@ -import { normalizeLineEnding } from "./utils"; import { IPlaygroundProject } from "../../../shared"; export function findLastIndex( diff --git a/website/tsconfig.json b/website/tsconfig.json index c89ec757..7ba57100 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -2,18 +2,15 @@ "compilerOptions": { "target": "esnext", "module": "commonjs", - "moduleResolution": "node16", + "moduleResolution": "Node", "strict": true, "outDir": "dist", "skipLibCheck": true, - "rootDir": "./src", "resolveJsonModule": true, "newLine": "LF", "sourceMap": true, - "jsx": "react", - "experimentalDecorators": true, - // to enable mobx decorators - "useDefineForClassFields": false + "useDefineForClassFields": false, + "noEmit": true }, - "include": ["src/**/*", "./node_modules/monaco-editor/monaco.d.ts"] + "exclude": ["src/**/*", "./node_modules/monaco-editor/monaco.d.ts"] } diff --git a/website/tsconfig.web.json b/website/tsconfig.web.json new file mode 100644 index 00000000..0e223beb --- /dev/null +++ b/website/tsconfig.web.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "outDir": "dist", + "skipLibCheck": true, + "rootDir": "./src", + "resolveJsonModule": true, + "newLine": "LF", + "sourceMap": true, + "jsx": "react", + "experimentalDecorators": true, + "useDefineForClassFields": false, + "noEmit": true + }, + "include": ["src/**/*", "./node_modules/monaco-editor/monaco.d.ts"] +} diff --git a/website/vscode-web-editors.tgz b/website/vscode-web-editors.tgz new file mode 100644 index 00000000..ea85ff18 Binary files /dev/null and b/website/vscode-web-editors.tgz differ diff --git a/website/yarn.lock b/website/yarn.lock index 07b09ad2..fdec9af1 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -487,6 +487,10 @@ dependencies: "@types/node" "*" +"@vscode/web-editors@./vscode-web-editors.tgz": + version "0.1.0" + resolved "./vscode-web-editors.tgz#657c1b47d50dfd1a457f660e3184fb88121f8b24" + "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"