mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 13:43:49 +01:00
first pass at monaco.
This commit is contained in:
parent
567c5dc230
commit
73ec97db87
@ -47,7 +47,6 @@
|
||||
|
||||
#script-editor-filename-wrapper {
|
||||
background-color: #555;
|
||||
margin-left: 6px;
|
||||
margin-right: 0;
|
||||
padding-left: 6px;
|
||||
width: 100%;
|
||||
|
80
package-lock.json
generated
80
package-lock.json
generated
@ -1,15 +1,17 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "0.52.0",
|
||||
"version": "0.52.5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "0.52.0",
|
||||
"version": "0.52.5",
|
||||
"hasInstallScript": true,
|
||||
"license": "SEE LICENSE IN license.txt",
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@monaco-editor/react": "^4.2.2",
|
||||
"@types/js-beautify": "^1.13.2",
|
||||
"@types/numeral": "0.0.25",
|
||||
"@types/react": "^16.8.6",
|
||||
"@types/react-dom": "^16.8.2",
|
||||
@ -688,6 +690,31 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@monaco-editor/loader": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.1.1.tgz",
|
||||
"integrity": "sha512-mkT4r4xDjIyOG9o9M6rJDSzEIeonwF80sYErxEvAAL4LncFVdcbNli8Qv6NDqF6nyv6sunuKkDzo4iFjxPL+uQ==",
|
||||
"dependencies": {
|
||||
"state-local": "^1.0.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"monaco-editor": ">= 0.21.0 < 1"
|
||||
}
|
||||
},
|
||||
"node_modules/@monaco-editor/react": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.2.2.tgz",
|
||||
"integrity": "sha512-yDDct+f/mZ946tJEXudvmMC8zXDygkELNujpJGjqJ0gS3WePZmS/IwBBsuJ8JyKQQC3Dy/+Ivg1sSpW+UvCv9g==",
|
||||
"dependencies": {
|
||||
"@monaco-editor/loader": "^1.1.1",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"monaco-editor": ">= 0.25.0 < 1",
|
||||
"react": "^16.8.0 || ^17.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mrmlnc/readdir-enhanced": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||
@ -751,6 +778,11 @@
|
||||
"integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/js-beautify": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-beautify/-/js-beautify-1.13.2.tgz",
|
||||
"integrity": "sha512-crV/441NhrynLIclg94i1wV6nX/6rU9ByUyn4muCrsL0HPd3nBzrt6kpQ9MQOB+HeYgLcRARteNJcbnYkp5OwA=="
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
|
||||
@ -10432,6 +10464,12 @@
|
||||
"yarn": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/monaco-editor": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.27.0.tgz",
|
||||
"integrity": "sha512-UhwP78Wb8w0ZSYoKXQNTV/0CHObp6NS3nCt51QfKE6sKyBo5PBsvuDOHoI2ooBakc6uIwByRLHVeT7+yXQe2fQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
@ -15040,6 +15078,11 @@
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/state-local": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
|
||||
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
|
||||
},
|
||||
"node_modules/state-toggle": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz",
|
||||
@ -19336,6 +19379,23 @@
|
||||
"react-is": "^16.8.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"@monaco-editor/loader": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.1.1.tgz",
|
||||
"integrity": "sha512-mkT4r4xDjIyOG9o9M6rJDSzEIeonwF80sYErxEvAAL4LncFVdcbNli8Qv6NDqF6nyv6sunuKkDzo4iFjxPL+uQ==",
|
||||
"requires": {
|
||||
"state-local": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"@monaco-editor/react": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.2.2.tgz",
|
||||
"integrity": "sha512-yDDct+f/mZ946tJEXudvmMC8zXDygkELNujpJGjqJ0gS3WePZmS/IwBBsuJ8JyKQQC3Dy/+Ivg1sSpW+UvCv9g==",
|
||||
"requires": {
|
||||
"@monaco-editor/loader": "^1.1.1",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"@mrmlnc/readdir-enhanced": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||
@ -19386,6 +19446,11 @@
|
||||
"integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/js-beautify": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-beautify/-/js-beautify-1.13.2.tgz",
|
||||
"integrity": "sha512-crV/441NhrynLIclg94i1wV6nX/6rU9ByUyn4muCrsL0HPd3nBzrt6kpQ9MQOB+HeYgLcRARteNJcbnYkp5OwA=="
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
|
||||
@ -27520,6 +27585,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"monaco-editor": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.27.0.tgz",
|
||||
"integrity": "sha512-UhwP78Wb8w0ZSYoKXQNTV/0CHObp6NS3nCt51QfKE6sKyBo5PBsvuDOHoI2ooBakc6uIwByRLHVeT7+yXQe2fQ==",
|
||||
"peer": true
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
@ -31433,6 +31504,11 @@
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"state-local": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
|
||||
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
|
||||
},
|
||||
"state-toggle": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz",
|
||||
|
@ -7,6 +7,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@monaco-editor/react": "^4.2.2",
|
||||
"@types/js-beautify": "^1.13.2",
|
||||
"@types/numeral": "0.0.25",
|
||||
"@types/react": "^16.8.6",
|
||||
"@types/react-dom": "^16.8.2",
|
||||
|
1
src/Fconf/Fconf.d.ts
vendored
Normal file
1
src/Fconf/Fconf.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare function parseFconfSettings(config: string): void;
|
@ -13,4 +13,5 @@ export interface IEngine {
|
||||
loadMissionContent: () => void;
|
||||
loadResleevingContent: () => void;
|
||||
loadStockMarketContent: () => void;
|
||||
loadTerminalContent: () => void;
|
||||
}
|
||||
|
3
src/Monaco/ui/Config.ts
Normal file
3
src/Monaco/ui/Config.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export interface Config {
|
||||
theme: string;
|
||||
}
|
34
src/Monaco/ui/ConfigPopup.tsx
Normal file
34
src/Monaco/ui/ConfigPopup.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Config } from "./Config";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { removePopup } from "../../ui/React/createPopup";
|
||||
|
||||
interface IProps {
|
||||
id: string;
|
||||
config: Config;
|
||||
save: (config: Config) => void;
|
||||
}
|
||||
|
||||
export function ConfigPopup(props: IProps): React.ReactElement {
|
||||
const [config, setConfig] = useState<Config>(props.config);
|
||||
function save() {
|
||||
props.save(config);
|
||||
removePopup(props.id);
|
||||
}
|
||||
|
||||
function setTheme(event: React.ChangeEvent<HTMLSelectElement>): void {
|
||||
setConfig(old => {
|
||||
old.theme = event.target.value;
|
||||
return old;
|
||||
});
|
||||
}
|
||||
|
||||
return (<>
|
||||
<select className="dropdown" onChange={setTheme} defaultValue={config.theme}>
|
||||
<option value="vs-dark">vs-dark</option>
|
||||
<option value="light">light</option>
|
||||
</select>
|
||||
<br />
|
||||
<StdButton text={"Save"} onClick={save} />
|
||||
</>);
|
||||
}
|
204
src/Monaco/ui/Root.tsx
Normal file
204
src/Monaco/ui/Root.tsx
Normal file
@ -0,0 +1,204 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
import { ConfigPopup } from "./ConfigPopup";
|
||||
import { Config } from "./Config";
|
||||
import { js_beautify as beautifyCode } from 'js-beautify';
|
||||
import { isValidFilePath } from "../../Terminal/DirectoryHelpers";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { IEngine } from "../../IEngine";
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import { parseFconfSettings } from "../../Fconf/Fconf";
|
||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||
import { Script } from "../../Script/Script";
|
||||
import { TextFile } from "../../TextFile";
|
||||
import { calculateRamUsage } from "../../Script/RamCalculations";
|
||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
|
||||
interface IProps {
|
||||
filename: string;
|
||||
code: string;
|
||||
player: IPlayer;
|
||||
engine: IEngine;
|
||||
};
|
||||
|
||||
// How to load function definition in monaco
|
||||
// https://github.com/Microsoft/monaco-editor/issues/1415
|
||||
// https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html
|
||||
// https://www.npmjs.com/package/@monaco-editor/react#development-playground
|
||||
|
||||
export function Root(props: IProps): React.ReactElement {
|
||||
const [filename, setFilename] = useState(props.filename);
|
||||
const [code, setCode] = useState<string>(props.code);
|
||||
const [ram, setRAM] = useState('');
|
||||
const [config, setConfig] = useState<Config>({theme: 'vs-dark'});
|
||||
|
||||
function save(): void {
|
||||
//CursorPositions.saveCursor(filename, cursor);
|
||||
|
||||
// TODO(hydroflame): re-enable the tutorial.
|
||||
// if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
|
||||
// //Make sure filename + code properly follow tutorial
|
||||
// if (filename !== "n00dles.script") {
|
||||
// dialogBoxCreate("Leave the script name as 'n00dles'!");
|
||||
// return;
|
||||
// }
|
||||
// code = code.replace(/\s/g, "");
|
||||
// if (code.indexOf("while(true){hack('n00dles');}") == -1) {
|
||||
// dialogBoxCreate("Please copy and paste the code from the tutorial!");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// //Save the script
|
||||
// let s = Player.getCurrentServer();
|
||||
// for (var i = 0; i < s.scripts.length; i++) {
|
||||
// if (filename == s.scripts[i].filename) {
|
||||
// s.scripts[i].saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
|
||||
// Engine.loadTerminalContent();
|
||||
// return iTutorialNextStep();
|
||||
// }
|
||||
// }
|
||||
|
||||
// // If the current script does NOT exist, create a new one
|
||||
// let script = new Script();
|
||||
// script.saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
|
||||
// s.scripts.push(script);
|
||||
|
||||
// return iTutorialNextStep();
|
||||
// }
|
||||
|
||||
if (filename == "") {
|
||||
dialogBoxCreate("You must specify a filename!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename !== ".fconf" && !isValidFilePath(filename)) {
|
||||
dialogBoxCreate("Script filename can contain only alphanumerics, hyphens, and underscores, and must end with an extension.");
|
||||
return;
|
||||
}
|
||||
|
||||
const s = props.player.getCurrentServer();
|
||||
if (filename === ".fconf") {
|
||||
try {
|
||||
parseFconfSettings(code);
|
||||
} catch(e) {
|
||||
dialogBoxCreate(`Invalid .fconf file: ${e}`);
|
||||
return;
|
||||
}
|
||||
} else if (isScriptFilename(filename)) {
|
||||
//If the current script already exists on the server, overwrite it
|
||||
for (let i = 0; i < s.scripts.length; i++) {
|
||||
if (filename == s.scripts[i].filename) {
|
||||
s.scripts[i].saveScript(code, props.player.currentServer, props.player.getCurrentServer().scripts);
|
||||
props.engine.loadTerminalContent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If the current script does NOT exist, create a new one
|
||||
const script = new Script();
|
||||
script.saveScript(code, props.player.currentServer, props.player.getCurrentServer().scripts);
|
||||
s.scripts.push(script);
|
||||
} else if (filename.endsWith(".txt")) {
|
||||
for (let i = 0; i < s.textFiles.length; ++i) {
|
||||
if (s.textFiles[i].fn === filename) {
|
||||
s.textFiles[i].write(code);
|
||||
props.engine.loadTerminalContent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
const textFile = new TextFile(filename, code);
|
||||
s.textFiles.push(textFile);
|
||||
} else {
|
||||
dialogBoxCreate("Invalid filename. Must be either a script (.script) or " +
|
||||
" or text file (.txt)")
|
||||
return;
|
||||
}
|
||||
props.engine.loadTerminalContent();
|
||||
}
|
||||
|
||||
function beautify(): void {
|
||||
setCode(code => beautifyCode(code, {
|
||||
indent_size: 4,
|
||||
brace_style: "preserve-inline",
|
||||
}));
|
||||
}
|
||||
|
||||
function onFilenameChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setFilename(event.target.value);
|
||||
}
|
||||
|
||||
function openConfig(): void {
|
||||
const id="script-editor-config-options-popup";
|
||||
createPopup(id, ConfigPopup, {
|
||||
id: id,
|
||||
config: {theme: config.theme},
|
||||
save: (config: Config) => setConfig(config),
|
||||
});
|
||||
}
|
||||
|
||||
function updateCode(newCode?: string): void {
|
||||
if(newCode === undefined) return;
|
||||
|
||||
setCode(newCode);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
async function updateRAM() {
|
||||
const codeCopy = code.repeat(1);
|
||||
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
||||
if (ramUsage > 0) {
|
||||
console.log(ramUsage);
|
||||
setRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
||||
return;
|
||||
}
|
||||
switch (ramUsage) {
|
||||
case RamCalculationErrorCode.ImportError: {
|
||||
setRAM("RAM: Import Error");
|
||||
break;
|
||||
}
|
||||
case RamCalculationErrorCode.URLImportError: {
|
||||
setRAM("RAM: HTTP Import Error");
|
||||
break;
|
||||
}
|
||||
case RamCalculationErrorCode.SyntaxError:
|
||||
default: {
|
||||
setRAM("RAM: Syntax Error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Promise<void>(() => undefined);
|
||||
}
|
||||
const id = setInterval(() => {
|
||||
console.log(code);
|
||||
updateRAM();
|
||||
}, 10000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
return (<div id="script-editor-wrapper">
|
||||
<div id="script-editor-filename-wrapper">
|
||||
<p id="script-editor-filename-tag"> <strong style={{backgroundColor:'#555'}}>Script name: </strong></p>
|
||||
<input id="script-editor-filename" type="text" maxLength={100} tabIndex={1} value={filename} onChange={onFilenameChange} />
|
||||
<StdButton text={"config"} onClick={openConfig} />
|
||||
</div>
|
||||
<Editor
|
||||
loading={<p>Loading script editor!</p>}
|
||||
height="80%"
|
||||
defaultLanguage="javascript"
|
||||
defaultValue={code}
|
||||
value={code}
|
||||
onChange={updateCode}
|
||||
theme="vs-dark"
|
||||
options={config}
|
||||
/>
|
||||
<div id="script-editor-buttons-wrapper">
|
||||
<StdButton text={"Beautify"} onClick={beautify} />
|
||||
<p id="script-editor-status-text" style={{display:"inline-block", margin:"10px"}}>{ram}</p>
|
||||
<button className="std-button" style={{display: "inline-block"}} onClick={save}>Save & Close (Ctrl/Cmd + b)</button>
|
||||
<a className="std-button" style={{display: "inline-block"}} target="_blank" href="https://bitburner.readthedocs.io/en/latest/index.html">Netscript Documentation</a>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
@ -100,6 +100,7 @@ import * as JSZip from "jszip";
|
||||
import * as FileSaver from "file-saver";
|
||||
import * as libarg from 'arg';
|
||||
import React from "react";
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
|
||||
function postNetburnerText() {
|
||||
|
@ -71,6 +71,7 @@ import {
|
||||
scriptEditorInit,
|
||||
updateScriptEditorContent,
|
||||
} from "./Script/ScriptHelpers";
|
||||
import { Root as ScriptEditorRoot } from "./Monaco/ui/Root";
|
||||
import { initForeignServers, AllServers } from "./Server/AllServers";
|
||||
import { Settings } from "./Settings/Settings";
|
||||
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||
@ -260,14 +261,16 @@ const Engine = {
|
||||
loadScriptEditorContent: function(filename = "", code = "") {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.scriptEditorContent.style.display = "block";
|
||||
try {
|
||||
getCurrentEditor().openScript(filename, code);
|
||||
} catch(e) {
|
||||
exceptionAlert(e);
|
||||
}
|
||||
|
||||
updateScriptEditorContent();
|
||||
routing.navigateTo(Page.ScriptEditor);
|
||||
|
||||
|
||||
const monaco = document.getElementById('monaco-editor');
|
||||
//https://www.npmjs.com/package/@monaco-editor/react#development-playground
|
||||
ReactDOM.render(
|
||||
<ScriptEditorRoot filename={filename} code={code} player={Player} engine={this} />,
|
||||
Engine.Display.scriptEditorContent,
|
||||
);
|
||||
|
||||
MainMenuLinks.ScriptEditor.classList.add("active");
|
||||
},
|
||||
|
||||
@ -504,6 +507,7 @@ const Engine = {
|
||||
Engine.Display.terminalContent.style.display = "none";
|
||||
Engine.Display.characterContent.style.display = "none";
|
||||
Engine.Display.scriptEditorContent.style.display = "none";
|
||||
ReactDOM.unmountComponentAtNode(Engine.Display.scriptEditorContent);
|
||||
|
||||
Engine.Display.activeScriptsContent.style.display = "none";
|
||||
ReactDOM.unmountComponentAtNode(Engine.Display.activeScriptsContent);
|
||||
|
@ -125,11 +125,8 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
||||
<input id="script-editor-filename" type="text" maxlength="100" tabindex="1" />
|
||||
</div>
|
||||
|
||||
<div id="ace-editor"></div>
|
||||
<form id="codemirror-form-wrapper"><textarea id="codemirror-editor"></textarea></form>
|
||||
<div id="codemirror-vim-command-display-wrapper">
|
||||
Key Buffer: <span id="codemirror-vim-command-display"></span>
|
||||
</div>
|
||||
<div id="monaco-editor"></div>
|
||||
|
||||
|
||||
<div id="script-editor-buttons-wrapper"></div> <!-- Buttons below script editor -->
|
||||
</div> <!-- End wrapper -->
|
||||
@ -175,6 +172,14 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
||||
<fieldset id="script-editor-option-flex4-fieldset"></fieldset>
|
||||
|
||||
</div> <!-- End script editor options panel -->
|
||||
|
||||
|
||||
<!-- TODO(hydroflame): remove this once Monaco is implemented -->
|
||||
<div id="ace-editor" style="display: none"></div>
|
||||
<form id="codemirror-form-wrapper" style="display: none"><textarea id="codemirror-editor"></textarea></form>
|
||||
<div id="codemirror-vim-command-display-wrapper" style="display: none">
|
||||
Key Buffer: <span id="codemirror-vim-command-display"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Terminal page -->
|
||||
|
Loading…
Reference in New Issue
Block a user