Begin rewriting frontend with web-componentes

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers
2024-04-05 16:10:53 -07:00
parent dd2ba26628
commit ca011cf48e
18 changed files with 1150 additions and 804 deletions

View File

@@ -13,293 +13,11 @@
<link rel="stylesheet" href="./main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/fontawesome.min.js"
integrity="sha512-C8qHv0HOaf4yoA7ISuuCTrsPX8qjolYTZyoFRKNA9dFKnxgzIHnYTOJhXQIt6zwpIFzCrRzUBuVgtC4e5K1nhA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/solid.min.js"
integrity="sha512-+fI924YJzeYFv7M0R29zJvRThPinSUOAmo5rpR9v6G4eWIbva/prHdZGSPN440vuf781/sOd/Fr+5ey0pqdW9w=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/fontawesome.min.css"
integrity="sha512-d0olNN35C6VLiulAobxYHZiXJmq+vl+BGIgAxQtD5+kqudro/xNMvv2yIHAciGHpExsIbKX3iLg+0B6d0k4+ZA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/solid.min.css"
integrity="sha512-pZlKGs7nEqF4zoG0egeK167l6yovsuL8ap30d07kA5AJUq+WysFlQ02DLXAmN3n0+H3JVz5ni8SJZnrOaYXWBA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/brands.min.js"
integrity="sha512-giAmE8KpCT6HP3DEwIvW9LYVnDs79iIaKEYFTjH62EWoglWgdAJa1ahiLUfoc3NFaAeWM6E3VdQyH1Ob2dmwQw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/brands.min.css"
integrity="sha512-8RxmFOVaKQe/xtg6lbscU9DU0IRhURWEuiI0tXevv+lXbAHfkpamD4VKFQRto9WgfOJDwOZ74c/s9Yesv3VvIQ=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body class="">
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
<div class="App">
<div id="modelShareLink" class="modal fade" tabindex="-1" aria-hidden="true" data-bs-theme="dark">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Share This Code!</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<input id="shareLinkText" type="text" class="form-control user-select-all"
aria-label="Recipient's username" aria-describedby="shareLinkCopyButton" readonly>
<button class="btn btn-outline-secondary" type="button" id="shareLinkCopyButton">Copy</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="offcanvas offcanvas-start" tabindex="-1" id="editorSettings" aria-labelledby="editorSettingsLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="editorSettingsLabel">Editor Settings</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="p-2">
<h6>Editor Keyboard Bindings</h6>
<div class="btn-group" role="group" aria-label="Editor Keyboard Bindings">
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindAce"
autocomplete="off" checked value="ace">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindAce">Ace</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindVim"
autocomplete="off" value="vim">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindVim">Vim</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindEmacs"
autocomplete="off" value="emacs">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindEmacs">Emacs</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindSublime"
autocomplete="off" value="sublime">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindSublime">Sublime</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindVSCode"
autocomplete="off" value="vscode">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindVSCode">VS Code</label>
</div>
</div>
<div class="p-2">
<h6>Editor Cursor Style</h6>
<div class="btn-group" role="group" aria-label="Editor Keyboard Bindings">
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorAce"
autocomplete="off" checked value="ace">
<label class="btn btn-outline-secondary" for="editorSettingsCursorAce">Ace</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorSlim"
autocomplete="off" value="slim">
<label class="btn btn-outline-secondary" for="editorSettingsCursorSlim">Slim</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorSmooth"
autocomplete="off" value="smooth">
<label class="btn btn-outline-secondary" for="editorSettingsCursorSmooth">Smooth</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorSmoothSlim"
autocomplete="off" value="smooth slim">
<label class="btn btn-outline-secondary" for="editorSettingsCursorSmoothSlim">Smooth And Slim</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorWide"
autocomplete="off" value="wide">
<label class="btn btn-outline-secondary" for="editorSettingsCursorWide">Wide</label>
</div>
</div>
<div class="input-group mb-3 p-2">
<span class="input-group-text" id="editorFontSizeLabel">Font Size</span>
<input id="editorSettingsFontSize" type="number" class="form-control" aria-label="font size"
aria-describedby="editorFontSizeLabel" value="16">
<span class="input-group-text">px</span>
</div>
<div class="p-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="editorSettingsRelativeLineNumbers">
<label class="form-check-label" for="editorSettingsRelativeLineNumbers">Relative Line Numbers</label>
</div>
</div>
</div>
</div>
<nav id="navBar" class="navbar navbar-default">
<div class="nav navbar-nav dropdown ps-2">
<button class="btn btn-outline-secondary" type="button" id="mainMenu" data-bs-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fa-solid fa-bars"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="mainMenu">
<li><button id="mainMenuShare" class="dropdown-item" type="button" data-bs-toggle="modal"
data-bs-target="#modelShareLink">Share</button></li>
<li><button id="mainMenuOpenFile" class="dropdown-item" type="button">Open File</button></li>
<li><button id="mainMenuSaveAs" class="dropdown-item" type="button">Save As</button></li>
<li>
<hr class="dropdown-divider">
</li>
<li><button id="mainMenuEditorSettings" class="dropdown-item" type="button" data-bs-toggle="offcanvas"
data-bs-target="#editorSettings" aria-controls="editorSettings">Editor Settings</button></li>
<li>
<hr class="dropdown-divider">
</li>
<li><button id="mainMenuKeyboardShortcuts" class="dropdown-item" type="button">Show Keyboard
Shortcuts</button></li>
</ul>
</div>
<div class="nav navbar-nav navbar-header ms-2">
<a class="navbar-brand active" aria-current="page" href="">Stationeers IC10 Emulator</a>
</div>
<div class="nav navbar-nav ms-2">
</div>
<div class="nav navbar-nav ms-auto navbar-right d-flex flex-row">
<a class="navbar-text mt-auto mb-auto align-self-center" href="https://github.com/ryex/ic10emu">View on Github
<i class="fa-brands fa-github"></i></a>
</div>
<!-- <div class="flex-grow w-100">&nbsp;</div> -->
<ul class="nav navbar-nav navbar-right flex-row d-sm-none d-none d-md-flex">
<p class="navbar-text mt-auto mb-auto align-self-center">Official Stationeers:</p>
<li role="presentation" class="">
<a href="https://store.steampowered.com/app/544550/Stationeers/">
<i class="fa-brands fa-steam fa-w-16"></i>
</a>
</li>
<li role="presentation" class="">
<a href="https://stationeers.com/">
<i class="fa-solid fa-globe fa-w-16"></i>
</a>
</li>
<li role="presentation" class="">
<a href="https://twitter.com/stationeers">
<i class="fa-brands fa-x-twitter"></i>
</a>
</li>
<li role="presentation" class="">
<a href="https://discordapp.com/invite/CxR3mRy">
<i class="fa-brands fa-discord"></i>
</a>
</li>
</ul>
</nav>
<div class="d-flex flex-row">
<div class="d-flex flex-column w-100">
<div id="editorContainer" class="p-1 h-100">
<div id="editor" class="w-100"></div>
</div>
<div id="statusBarContainer" class="p-1 mt-auto">
<div id="statusBar" class="w-100 text-body">IC10 editor!</div>
</div>
</div>
<div class="d-flex flex-column flex-shrink-1">
<div id="virtualMachine">
<div id="vmActiveIC" class="container ">
<div class="ms-1 me-2 pb-2 row border border-secondary rounded bg-secondary bg-opacity-10">
<div class="mt-2 col">
<div id="vmControls" class="btn-group-vertical btn-group-sm " role="group"
aria-label="Virtual Machine Controls">
<button id="vmControlRun" type="button" class="btn btn-primary">Run</button>
<button id="vmControlStep" type="button" class="btn btn-secondary">Step</button>
<button id="vmControlReset" type="button" class="btn btn-warning">Reset</button>
</div>
</div>
<div id="vmActiveICState" class="mt-2 col-9 g-4">
<div class="hstack g-0">
<div>Instruction Pointer</div>
<div class="ms-auto" id="vmActiveICStateIP"></div>
</div>
<hr />
<div class="hstack g-0">
<div>Last Run Operations Count</div>
<div class="ms-auto" id="vmActiveICStateICount"></div>
</div>
<hr />
<div class="hstack g-0">
<div>Last State</div>
<div class="ms-auto" id="vmActiveICStateLastRun"></div>
</div>
</div>
</div>
<div class="row mt-1 ms-1 me-1">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="offcanvas"
data-bs-target="#vmDevices" aria-expanded="false"
aria-controls="vmDevices">View All Devices <span id="vmViewDeviceCount"></span></button>
</div>
<div class="row p2">
<div class="collapse mt-1" id=vmDeviceSummaryCollapse>
</div>
</div>
<div class="row mt-2">
<div class="accordion vm_accordion" id="vmActiveIC">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseDeviceSummary" aria-expanded="false"
aria-controls="collapseDeviceSummary">
Device Summary
</button>
</h2>
<div id="collapseDeviceSummary" class="accordion-collapse collapse">
<div class="accordion-body">
<div id="vmDeviceSummary" class="card card-body vm_device_summary">
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseReg" aria-expanded="true" aria-controls="collapseReg">
Registers
</button>
</h2>
<div id="collapseReg" class="accordion-collapse collapse show">
<div class="accordion-body">
<div id="vmActiveRegisters" class="vm_reg">
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseStack" aria-expanded="false" aria-controls="collapseStack">
Stack
</button>
</h2>
<div id="collapseStack" class="accordion-collapse collapse">
<div class="accordion-body">
<div id="vmActiveStack" class="vm_stack">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.7/ace.js" type="text/javascript" charset="utf-8"></script> -->
<script>
</script>
<div class="offcanvas offcanvas-bottom" tabindex="-1" id="vmDevices" aria-labelledby="vmDevicesLabel"
data-bs-scroll="true" data-bs-backdrop="false">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="vmDevicesLabel">Devices</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="p-2" id="vmDevicesOCBody"></div>
</div>
</div>
<ic10emu-app></ic10emu-app>
</body>
</html>

305
www/src/index.old.html Normal file
View File

@@ -0,0 +1,305 @@
<!DOCTYPE html>
<html data-bs-theme="dark">
<head>
<meta charset="utf-8">
<title>Stationeers IC10 Emulator</title>
<meta property="og:title" content="Stationeers IC10 Editor &amp; Emulator" />
<meta property="og:description"
content="A feature packed code editor for Stationeers IC10 code, paired with a robust debugger and emulator. Edit, test, and share code." />
<meta property="og:image" content="https://ryex.github.io/ic10emu/img/embed_preview.png" />
<meta property="og:url" content="https://ryex.github.io/ic10emu/" />
<link rel="stylesheet" href="./main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/fontawesome.min.js"
integrity="sha512-C8qHv0HOaf4yoA7ISuuCTrsPX8qjolYTZyoFRKNA9dFKnxgzIHnYTOJhXQIt6zwpIFzCrRzUBuVgtC4e5K1nhA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/solid.min.js"
integrity="sha512-+fI924YJzeYFv7M0R29zJvRThPinSUOAmo5rpR9v6G4eWIbva/prHdZGSPN440vuf781/sOd/Fr+5ey0pqdW9w=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/fontawesome.min.css"
integrity="sha512-d0olNN35C6VLiulAobxYHZiXJmq+vl+BGIgAxQtD5+kqudro/xNMvv2yIHAciGHpExsIbKX3iLg+0B6d0k4+ZA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/solid.min.css"
integrity="sha512-pZlKGs7nEqF4zoG0egeK167l6yovsuL8ap30d07kA5AJUq+WysFlQ02DLXAmN3n0+H3JVz5ni8SJZnrOaYXWBA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/brands.min.js"
integrity="sha512-giAmE8KpCT6HP3DEwIvW9LYVnDs79iIaKEYFTjH62EWoglWgdAJa1ahiLUfoc3NFaAeWM6E3VdQyH1Ob2dmwQw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/brands.min.css"
integrity="sha512-8RxmFOVaKQe/xtg6lbscU9DU0IRhURWEuiI0tXevv+lXbAHfkpamD4VKFQRto9WgfOJDwOZ74c/s9Yesv3VvIQ=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body class="">
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
<div class="App">
<div id="modelShareLink" class="modal fade" tabindex="-1" aria-hidden="true" data-bs-theme="dark">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Share This Code!</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<input id="shareLinkText" type="text" class="form-control user-select-all"
aria-label="Recipient's username" aria-describedby="shareLinkCopyButton" readonly>
<button class="btn btn-outline-secondary" type="button" id="shareLinkCopyButton">Copy</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="offcanvas offcanvas-start" tabindex="-1" id="editorSettings" aria-labelledby="editorSettingsLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="editorSettingsLabel">Editor Settings</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="p-2">
<h6>Editor Keyboard Bindings</h6>
<div class="btn-group" role="group" aria-label="Editor Keyboard Bindings">
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindAce"
autocomplete="off" checked value="ace">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindAce">Ace</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindVim"
autocomplete="off" value="vim">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindVim">Vim</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindEmacs"
autocomplete="off" value="emacs">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindEmacs">Emacs</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindSublime"
autocomplete="off" value="sublime">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindSublime">Sublime</label>
<input type="radio" class="btn-check" name="editorKeybindRadio" id="editorSettingsKeybindVSCode"
autocomplete="off" value="vscode">
<label class="btn btn-outline-secondary" for="editorSettingsKeybindVSCode">VS Code</label>
</div>
</div>
<div class="p-2">
<h6>Editor Cursor Style</h6>
<div class="btn-group" role="group" aria-label="Editor Keyboard Bindings">
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorAce"
autocomplete="off" checked value="ace">
<label class="btn btn-outline-secondary" for="editorSettingsCursorAce">Ace</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorSlim"
autocomplete="off" value="slim">
<label class="btn btn-outline-secondary" for="editorSettingsCursorSlim">Slim</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorSmooth"
autocomplete="off" value="smooth">
<label class="btn btn-outline-secondary" for="editorSettingsCursorSmooth">Smooth</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorSmoothSlim"
autocomplete="off" value="smooth slim">
<label class="btn btn-outline-secondary" for="editorSettingsCursorSmoothSlim">Smooth And Slim</label>
<input type="radio" class="btn-check" name="editorCursorRadio" id="editorSettingsCursorWide"
autocomplete="off" value="wide">
<label class="btn btn-outline-secondary" for="editorSettingsCursorWide">Wide</label>
</div>
</div>
<div class="input-group mb-3 p-2">
<span class="input-group-text" id="editorFontSizeLabel">Font Size</span>
<input id="editorSettingsFontSize" type="number" class="form-control" aria-label="font size"
aria-describedby="editorFontSizeLabel" value="16">
<span class="input-group-text">px</span>
</div>
<div class="p-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="editorSettingsRelativeLineNumbers">
<label class="form-check-label" for="editorSettingsRelativeLineNumbers">Relative Line Numbers</label>
</div>
</div>
</div>
</div>
<nav id="navBar" class="navbar navbar-default">
<div class="nav navbar-nav dropdown ps-2">
<button class="btn btn-outline-secondary" type="button" id="mainMenu" data-bs-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fa-solid fa-bars"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="mainMenu">
<li><button id="mainMenuShare" class="dropdown-item" type="button" data-bs-toggle="modal"
data-bs-target="#modelShareLink">Share</button></li>
<li><button id="mainMenuOpenFile" class="dropdown-item" type="button">Open File</button></li>
<li><button id="mainMenuSaveAs" class="dropdown-item" type="button">Save As</button></li>
<li>
<hr class="dropdown-divider">
</li>
<li><button id="mainMenuEditorSettings" class="dropdown-item" type="button" data-bs-toggle="offcanvas"
data-bs-target="#editorSettings" aria-controls="editorSettings">Editor Settings</button></li>
<li>
<hr class="dropdown-divider">
</li>
<li><button id="mainMenuKeyboardShortcuts" class="dropdown-item" type="button">Show Keyboard
Shortcuts</button></li>
</ul>
</div>
<div class="nav navbar-nav navbar-header ms-2">
<a class="navbar-brand active" aria-current="page" href="">Stationeers IC10 Emulator</a>
</div>
<div class="nav navbar-nav ms-2">
</div>
<div class="nav navbar-nav ms-auto navbar-right d-flex flex-row">
<a class="navbar-text mt-auto mb-auto align-self-center" href="https://github.com/ryex/ic10emu">View on Github
<i class="fa-brands fa-github"></i></a>
</div>
<!-- <div class="flex-grow w-100">&nbsp;</div> -->
<ul class="nav navbar-nav navbar-right flex-row d-sm-none d-none d-md-flex">
<p class="navbar-text mt-auto mb-auto align-self-center">Official Stationeers:</p>
<li role="presentation" class="">
<a href="https://store.steampowered.com/app/544550/Stationeers/">
<i class="fa-brands fa-steam fa-w-16"></i>
</a>
</li>
<li role="presentation" class="">
<a href="https://stationeers.com/">
<i class="fa-solid fa-globe fa-w-16"></i>
</a>
</li>
<li role="presentation" class="">
<a href="https://twitter.com/stationeers">
<i class="fa-brands fa-x-twitter"></i>
</a>
</li>
<li role="presentation" class="">
<a href="https://discordapp.com/invite/CxR3mRy">
<i class="fa-brands fa-discord"></i>
</a>
</li>
</ul>
</nav>
<div class="d-flex flex-row">
<div class="d-flex flex-column w-100">
<div id="editorContainer" class="p-1 h-100">
<div id="editor" class="w-100"></div>
</div>
<div id="statusBarContainer" class="p-1 mt-auto">
<div id="statusBar" class="w-100 text-body">IC10 editor!</div>
</div>
</div>
<div class="d-flex flex-column flex-shrink-1">
<div id="virtualMachine">
<div id="vmActiveIC" class="container ">
<div class="ms-1 me-2 pb-2 row border border-secondary rounded bg-secondary bg-opacity-10">
<div class="mt-2 col">
<div id="vmControls" class="btn-group-vertical btn-group-sm " role="group"
aria-label="Virtual Machine Controls">
<button id="vmControlRun" type="button" class="btn btn-primary">Run</button>
<button id="vmControlStep" type="button" class="btn btn-secondary">Step</button>
<button id="vmControlReset" type="button" class="btn btn-warning">Reset</button>
</div>
</div>
<div id="vmActiveICState" class="mt-2 col-9 g-4">
<div class="hstack g-0">
<div>Instruction Pointer</div>
<div class="ms-auto" id="vmActiveICStateIP"></div>
</div>
<hr />
<div class="hstack g-0">
<div>Last Run Operations Count</div>
<div class="ms-auto" id="vmActiveICStateICount"></div>
</div>
<hr />
<div class="hstack g-0">
<div>Last State</div>
<div class="ms-auto" id="vmActiveICStateLastRun"></div>
</div>
</div>
</div>
<div class="row mt-1 ms-1 me-1">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="offcanvas"
data-bs-target="#vmDevices" aria-expanded="false"
aria-controls="vmDevices">View All Devices <span id="vmViewDeviceCount"></span></button>
</div>
<div class="row p2">
<div class="collapse mt-1" id=vmDeviceSummaryCollapse>
</div>
</div>
<div class="row mt-2">
<div class="accordion vm_accordion" id="vmActiveIC">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseDeviceSummary" aria-expanded="false"
aria-controls="collapseDeviceSummary">
Device Summary
</button>
</h2>
<div id="collapseDeviceSummary" class="accordion-collapse collapse">
<div class="accordion-body">
<div id="vmDeviceSummary" class="card card-body vm_device_summary">
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseReg" aria-expanded="true" aria-controls="collapseReg">
Registers
</button>
</h2>
<div id="collapseReg" class="accordion-collapse collapse show">
<div class="accordion-body">
<div id="vmActiveRegisters" class="vm_reg">
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseStack" aria-expanded="false" aria-controls="collapseStack">
Stack
</button>
</h2>
<div id="collapseStack" class="accordion-collapse collapse">
<div class="accordion-body">
<div id="vmActiveStack" class="vm_stack">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.7/ace.js" type="text/javascript" charset="utf-8"></script> -->
<script>
</script>
<div class="offcanvas offcanvas-bottom" tabindex="-1" id="vmDevices" aria-labelledby="vmDevicesLabel"
data-bs-scroll="true" data-bs-backdrop="false">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="vmDevicesLabel">Devices</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="p-2" id="vmDevicesOCBody"></div>
</div>
</div>
</body>
</html>

15
www/src/js/app/app.ts Normal file
View File

@@ -0,0 +1,15 @@
import { HTMLTemplateResult, html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
import { BaseElement } from "../components";
import "./nav.ts";
@customElement('ic10emu-app')
export class App extends BaseElement {
constructor() {
super();
}
protected render(): HTMLTemplateResult {
return html`<app-nav></app-nav>`;
}
}

12
www/src/js/app/icons.ts Normal file
View File

@@ -0,0 +1,12 @@
import { registerIconLibrary } from "@shoelace-style/shoelace/dist/utilities/icon-library.js";
registerIconLibrary("fa", {
resolver: (name) => {
const filename = name.replace(/^fa[rbs]-/, "");
let folder = "regular";
if (name.substring(0, 4) === "fas-") folder = "solid";
if (name.substring(0, 4) === "fab-") folder = "brands";
return `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/svgs/${folder}/${filename}.svg`;
},
mutator: (svg) => svg.setAttribute("fill", "currentColor"),
});

4
www/src/js/app/index.ts Normal file
View File

@@ -0,0 +1,4 @@
import { App } from "./app";
import { Nav } from "./nav";
import "./icons";
export { App, Nav }

151
www/src/js/app/nav.ts Normal file
View File

@@ -0,0 +1,151 @@
import { HTMLTemplateResult, html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
import { BaseElement } from "../components";
import "@shoelace-style/shoelace/dist/components/icon-button/icon-button.js";
import "@shoelace-style/shoelace/dist/components/menu/menu.js";
import "@shoelace-style/shoelace/dist/components/divider/divider.js";
import "@shoelace-style/shoelace/dist/components/menu-item/menu-item.js";
import "@shoelace-style/shoelace/dist/components/dropdown/dropdown.js";
@customElement("app-nav")
export class Nav extends BaseElement {
static styles = css`
.nav {
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.navbar {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: left;
justify-content: space-between;
padding: 0.5rem 0;
}
.navbar-nav {
display: flex;
flex-direction: column;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.ps-2 {
padding-left: 0.5rem !important;
}
.ms-2 {
margin-left: 0.5rem !important;
}
.ms-auto {
margin-left: auto !important;
}
.flex-row {
flex-direction: row !important;
}
.d-flex {
display: flex !important;
}
@media (min-width: 768px) .d-md-flex {
display: flex !important;
}
@media (min-width: 576px) .d-sm-none {
display: none !important;
}
.d-none {
display: none !important;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
.navbar-text {
padding: 0;
padding-right: 10px;
position: relative;
color: #fff;
}
`;
constructor() {
super();
}
protected render(): HTMLTemplateResult {
return html`
<nav id="navBar" class="navbar navbar-default">
<div class="nav navbar-nav ps-2">
<sl-dropdown>
<sl-icon-button
library="fa"
name="fas-bars"
slot="trigger"
label="Main Menu"
></sl-icon-button>
<sl-menu>
<sl-menu-item value="share">Share</sl-menu-item>
<sl-menu-item value="openFile">Open File</sl-menu-item>
<sl-menu-item value="saveAs">Save As</sl-menu-item>
<sl-devider></sl-devider>
<sl-menu-item value="editorSettings"
>Editor Settings</sl-menu-item
>
<sl-devider></sl-devider>
<sl-menu-item value="keyboardShortcuts"
>Editor Keyboard Shortcuts</sl-menu-item
>
</sl-menu>
</sl-dropdown>
</div>
<div class="nav navbar-nav navbar-header ms-2">
<a class="navbar-brand" aria-current="page" href=""
>Stationeers IC10 Emulator</a
>
</div>
<div class="nav navbar-nav ms-auto navbar-right d-flex flex-row">
<a
class="navbar-text mt-auto mb-auto align-self-center"
href="https://github.com/ryex/ic10emu"
>View on Github <i class="fa-brands fa-github"></i
></a>
</div>
<!-- <div class="flex-grow w-100">&nbsp;</div> -->
<ul
class="nav navbar-nav navbar-right flex-row d-sm-none d-none d-md-flex"
>
<p class="navbar-text mt-auto mb-auto align-self-center">
Official Stationeers:
</p>
<li role="presentation" class="">
<a href="https://store.steampowered.com/app/544550/Stationeers/">
<i class="fa-brands fa-steam fa-w-16"></i>
<sl-icon library="fa" name="fab-steam"></sl-icon>
</a>
</li>
<li role="presentation" class="">
<a href="https://stationeers.com/">
<sl-icon library="fa" name="fas-globe"></sl-icon>
</a>
</li>
<li role="presentation" class="">
<a href="https://twitter.com/stationeers">
<sl-icon library="fa" name="fab-x-twitter"></sl-icon>
</a>
</li>
<li role="presentation" class="">
<a href="https://discordapp.com/invite/CxR3mRy">
<i class="fa-brands fa-discord"></i>
<sl-icon library="fa" name="fab-discord"></sl-icon>
</a>
</li>
</ul>
</nav>
`;
}
}

View File

@@ -0,0 +1,7 @@
import { LitElement, css } from "lit";
import shoelaceDark from "@shoelace-style/shoelace/dist/themes/dark.styles.js";
export class BaseElement extends LitElement {
// Some default styles
static styles = shoelaceDark;
}

View File

@@ -0,0 +1,3 @@
import { BaseElement } from './base';
export { BaseElement }

View File

@@ -1,19 +1,10 @@
// import { ace } from "./ace.js"
import ace from "ace-builds";
import "ace-builds/esm-resolver";
// patch prompt ext
ace.config.setModuleLoader('ace/ext/prompt', () => import('./prompt_patch'));
ace.config.setDefaultValue("session", "theme", "ace/theme/one_dark");
import "ace-builds/src-noconflict/ext-language_tools";
ace.require("ace/ext/language_tools");
import "./ic10_mode";
import { AceLanguageClient } from "ace-linters/build/ace-language-client";
import { IC10EditorUI } from './ui';
import { Range } from 'ace-builds';
import { IC10EditorUI } from "./ui";
import { Range } from "ace-builds";
import { App } from "../index";
import { Session } from "../session";
@@ -24,13 +15,12 @@ ace.config.loadModule("ace/ext/language_tools");
import { Mode as TextMode } from "ace-builds/src-noconflict/mode-text";
async function setupLspWorker() {
// Create a web worker
let worker = new Worker(new URL('./lspWorker.ts', import.meta.url));
let worker = new Worker(new URL("./lspWorker.ts", import.meta.url));
const loaded = (w: Worker) =>
new Promise(r => w.addEventListener("message", r, { once: true }));
new Promise((r) => w.addEventListener("message", r, { once: true }));
await Promise.all([loaded(worker)]);
// Register the editor with the language provider
@@ -38,19 +28,115 @@ async function setupLspWorker() {
}
declare global {
interface Window { Editor: IC10Editor }
interface Window {
Editor: IC10Editor;
}
}
class IC10Editor {
import { BaseElement } from "../components";
import { html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
@customElement("ace-ic10")
class IC10Editor extends BaseElement {
mode: string;
settings: { keyboard: string; cursor: string; fontSize: number; relativeLineNumbers: boolean; };
aceEditor: ace.Ace.Editor;
settings: {
keyboard: string;
cursor: string;
fontSize: number;
relativeLineNumbers: boolean;
};
sessions: Map<number, ace.Ace.EditSession>;
active_session: number;
active_line_markers: Map<number, number | null>;
languageProvider: null | AceLanguageClient;
@property({ type: Number })
accessor active_session: number = 0;
active_line_markers: Map<number, number | null> = new Map();
languageProvider?: AceLanguageClient;
ui: IC10EditorUI;
constructor(session_id: number) {
static styles = css`
:host {
display: block;
width: 100%;
height: 100%;
}
#editor {
border: var(--lae-border, 1px solid var(--lumo-contrast-20pct));
border-radius: var(--lae-border-radius, var(--lumo-border-radius));
@apply --ace-widget-editor;
}
#editorStatusbar {
z-index: 9 !important;
position: absolute !important;
right: 4px;
bottom: 4px;
}
.ace_status-indicator {
background-color: var(--las-background-color, #777);
color: var(--las-color, white);
text-align: center;
border: none;
border-radius: var(--las-border-radius, 7px);
padding-right: 3px;
padding-left: 3px;
padding-bottom: 1px;
font-size: small;
opacity: 0.9;
}
.hide_statusbar {
display: none;
}
.ace_marker-layer .green {
background-color: var(--lumo-success-color);
color: var(--lumo-primary-contrast-color);
position: absolute;
}
.ace_marker-layer .darkGrey {
background-color: var(--lumo-shade-50pct);
color: var(--lumo-primary-contrast-color);
position: absolute;
}
.ace_marker-layer .red {
background-color: var(--lumo-error-color);
color: var(--lumo-primary-contrast-color);
position: absolute;
}
.ace_marker-layer .blue {
background-color: var(--lumo-primary-color);
color: var(--lumo-primary-contrast-color);
position: absolute;
}
.ace_marker-layer .orange {
background-color: #ff9900;
color: #555;
position: absolute;
}
.ace_placeholder {
color: #808080 !important;
font-family: var(--lumo-font-family) !important;
transform: scale(1) !important;
opacity: 1 !important;
font-style: italic !important;
}
`;
initialInit: boolean;
editorDiv: HTMLElement;
editorContainerDiv: HTMLElement;
editorStatusbarDiv: HTMLElement;
editor: ace.Ace.Editor;
statusBar: any;
snippetManager: any;
observer: ResizeObserver;
private _statusbarIndex: number;
private _statusbar: any;
vScrollbarObserver: IntersectionObserver;
hScrollbarObserver: any;
constructor() {
super();
console.log('constructing editor')
window.Editor = this;
this.mode = "ace/mode/ic10";
@@ -61,33 +147,14 @@ class IC10Editor {
relativeLineNumbers: false,
};
this.aceEditor = ace.edit('editor', {
mode: this.mode,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
theme: "ace/theme/one_dark",
fontSize: 16,
customScrollbar: false,
firstLineNumber: 0,
printMarginColumn: 52,
placeholder: "Your code goes here ...",
});
this.sessions = new Map();
this.sessions.set(session_id, this.aceEditor.getSession());
this.active_session = session_id;
this.bindSession(session_id, this.sessions.get(session_id));
this.active_line_markers = new Map();
this.active_line_markers.set(session_id, null);
this.languageProvider = null;
this.ui = new IC10EditorUI(this);
// this.ui = new IC10EditorUI(this);
const that = this;
App.session.onLoad((session: Session ) => {
App.session.onLoad((session: Session) => {
const updated_ids = [];
for (const [id, _] of session.programs) {
updated_ids.push(id);
@@ -99,7 +166,6 @@ class IC10Editor {
that.destroySession(id);
}
}
});
App.session.loadFromFragment();
@@ -114,17 +180,220 @@ class IC10Editor {
}
const session = that.sessions.get(id);
if (session) {
that.active_line_markers.set(id, session.addMarker(new Range(active_line, 0, active_line, 1), "vm_ic_active_line", "fullLine", true));
that.active_line_markers.set(
id,
session.addMarker(
new Range(active_line, 0, active_line, 1),
"vm_ic_active_line",
"fullLine",
true,
),
);
if (that.active_session == id) {
// editor.resize(true);
// TODO: Scroll to line if vm was stepped
//that.aceEditor.scrollToLine(active_line, true, true, ()=>{})
//that.editor.scrollToLine(active_line, true, true, ()=>{})
}
}
}
}
})
});
}
render() {
return html`
<div
id="editorContainer"
style="height: 100%; width: 100%; position: relative;"
>
<div
id="editor"
style="position: absolute; top: 0; right: 0; bottom: 0; left: 0;"
></div>
<div id="editorStatusbar"></div>
</div>
`;
}
async firstUpdated() {
console.log('editor firstUpdated')
if (!ace.require("ace/ext/language_tools")) {
await import("ace-builds/src-noconflict/ext-language_tools");
}
if (!ace.require("ace/ext/statusbar")) {
await import("ace-builds/src-noconflict/ext-statusbar");
}
if (!ace.require("ace/mode/ic10")) {
await import("./ic10_mode");
}
// patch prompt ext
ace.config.setModuleLoader(
"ace/ext/prompt",
() => import("./prompt_patch"),
);
ace.config.setDefaultValue("session", "theme", "ace/theme/one_dark");
this.initialInit = true;
this.editorDiv = this.shadowRoot.getElementById("editor");
this.editorContainerDiv = this.shadowRoot.getElementById("editorContainer");
this.editorStatusbarDiv = this.shadowRoot.getElementById("editorStatusbar");
this.editor = ace.edit(this.editorDiv, {
mode: this.mode,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
theme: "ace/theme/one_dark",
fontSize: 16,
customScrollbar: false,
firstLineNumber: 0,
printMarginColumn: 52,
placeholder: "Your code goes here ...",
});
this.editor.renderer.attachToShadowRoot();
this.statusBar = ace.require("ace/ext/statusbar").StatusBar;
this.snippetManager = ace.require("ace/snippets").snippetManager;
this.sessions.set(this.active_session, this.editor.getSession());
this.bindSession(
this.active_session,
this.sessions.get(this.active_session),
);
this.active_line_markers.set(this.active_session, null);
const worker = await setupLspWorker();
this.setupLsp(worker);
const that = this;
// when the CSS resize Property is added (to a container-div or ace-ic10 )
// the correct sizing is maintained (after user resize)
document.addEventListener("mouseup", function (e) {
that.resizeEditor();
});
this.observer = new ResizeObserver(function (entries) {
entries.forEach(function (entry) {
that.resizeEditor();
});
});
this.observer.observe(this.editorContainerDiv);
this.initializeEditor();
}
initializeEditor() {
let editor = this.editor;
// change -> possibility to allow saving the value without having to wait for blur
editor.on("change", () => this.editorChangeAction());
this._statusbarIndex = 1;
this._statusbar = new this.statusBar(
this.editor,
this.editorStatusbarDiv,
this._statusbarIndex,
);
this._statusbar.updateStatus(this.editor);
this.vScrollbarObserver = new IntersectionObserver(
this._vScrollbarHandler.bind(this),
{ root: null },
);
this.vScrollbarObserver.observe(
this.shadowRoot.querySelector(".ace_scrollbar-v"),
);
this.hScrollbarObserver = new IntersectionObserver(
this._hScrollbarHandler.bind(this),
{ root: null },
);
this.hScrollbarObserver.observe(
this.shadowRoot.querySelector(".ace_scrollbar-h"),
);
}
resizeEditor() {
if (this.editor == undefined) {
this.addEventListener("editor-ready", () => this._resizeEditor(), {
once: true,
});
} else {
this._resizeEditor();
}
}
/** @private */
_resizeEditor() {
this.editor.resize();
}
/** @private */
_vScrollbarHandler() {
var vScrollbar = this.shadowRoot.querySelector(
".ace_scrollbar-v",
) as HTMLDivElement;
if (vScrollbar.style.display === "none") {
this.editorStatusbarDiv.style.right = "4px";
} else {
let width = vScrollbar.offsetWidth - vScrollbar.clientWidth;
if (width === undefined || width === null) {
width = 20;
}
this.editorStatusbarDiv.style.right = width + 4 + "px";
}
}
/** @private */
_hScrollbarHandler() {
var hScrollbar = this.shadowRoot.querySelector(
".ace_scrollbar-h",
) as HTMLDivElement;
if (hScrollbar.style.display === "none") {
this.editorStatusbarDiv.style.bottom = "4px";
} else {
let height = hScrollbar.offsetHeight - hScrollbar.clientHeight;
if (height === undefined || height === null) {
height = 20;
}
this.editorStatusbarDiv.style.bottom = height + 4 + "px";
}
}
editorChangeAction() {
this.dispatchEvent(
new CustomEvent("editor-change", {
detail: {
value: this.editorValue,
},
}),
);
}
get editorValue() {
if (this.editor == undefined) {
return "";
}
return this.editor.getValue();
}
set editorValue(value) {
if (this.editor == undefined || value === undefined) {
return;
}
this.editor.setValue(value, 1);
}
focusEditor() {
if (this.editor == undefined) {
this.addEventListener("editor-ready", (e) => this.editor.focus(), {
once: true,
});
} else {
this.editor.focus();
}
}
createOrSetSession(session_id: number, content: any) {
@@ -141,7 +410,7 @@ class IC10Editor {
const session = ace.createEditSession("", this.mode as any);
session.setOptions({
firstLineNumber: 0,
})
});
this.sessions.set(session_id, session);
this.bindSession(session_id, session);
}
@@ -155,12 +424,7 @@ class IC10Editor {
};
// Create a language provider for web worker
this.languageProvider = AceLanguageClient.for(serverData as any);
(this.languageProvider as any).registerEditor(this.aceEditor);
// for (const session_id of this.sessions.keys()) {
// let options = {};
// (this.languageProvider as any).setSessionOptions(this.sessions.get(session_id), options);
// }
(this.languageProvider as any).registerEditor(this.editor);
}
@@ -168,7 +432,7 @@ class IC10Editor {
if (!this.sessions.get(session_id)) {
return false;
}
this.aceEditor.setSession(this.sessions.get(session_id));
this.editor.setSession(this.sessions.get(session_id));
this.active_session = session_id;
return true;
}
@@ -200,7 +464,7 @@ class IC10Editor {
}
const session = this.sessions.get(session_id);
this.sessions.delete(session_id);
if (this.active_session = session_id) {
if ((this.active_session = session_id)) {
this.activateSession(this.sessions.entries().next().value);
}
session.destroy();
@@ -208,19 +472,11 @@ class IC10Editor {
}
bindSession(session_id: number, session: ace.Ace.EditSession) {
session.on('change', () => {
session.on("change", () => {
var val = session.getValue();
window.App.session.setProgramCode(session_id, val);
});
}
}
export { IC10Editor, setupLspWorker };
export { IC10Editor };

View File

@@ -11,19 +11,19 @@ class IC10EditorUI {
that.ic10editor = ic10editor;
that.ic10editor.aceEditor.commands.addCommand({
name: "showSettingsMenu",
description: "Show settings menu",
bindKey: { win: "Ctrl-,", mac: "Command-," },
exec: (_editor: ace.Ace.Editor) => {
const offCanvas = new Offcanvas(document.getElementById("editorSettings"));
offCanvas.toggle();
}
} as any);
// that.ic10editor.editor.commands.addCommand({
// name: "showSettingsMenu",
// description: "Show settings menu",
// bindKey: { win: "Ctrl-,", mac: "Command-," },
// exec: (_editor: ace.Ace.Editor) => {
// const offCanvas = new Offcanvas(document.getElementById("editorSettings"));
// offCanvas.toggle();
// }
// } as any);
ace.config.loadModule("ace/ext/keyboard_menu", function (module) {
console.log("keybinding_menu loaded");
module.init(that.ic10editor.aceEditor);
module.init(that.ic10editor.editor);
});
that.ic10editor.loadEditorSettings();
@@ -58,21 +58,17 @@ class IC10EditorUI {
that.updateEditorSettings();
});
console.log(that.ic10editor.aceEditor.getOption('keyboardHandler'));
console.log(that.ic10editor.editor.getOption('keyboardHandler'));
that.ic10editor.aceEditor.setTheme("ace/theme/one_dark");
ace.config.loadModule("ace/ext/statusbar", function (module) {
const statusBar = new module.StatusBar(that.ic10editor.aceEditor, document.getElementById("statusBar"));
statusBar.updateStatus(that.ic10editor.aceEditor);
});
that.ic10editor.editor.setTheme("ace/theme/one_dark");
that.ic10editor.aceEditor.setAutoScrollEditorIntoView(true);
that.ic10editor.editor.setAutoScrollEditorIntoView(true);
}
updateEditorSettings() {
const settings = this.ic10editor.settings;
const editor = this.ic10editor.aceEditor;
const editor = this.ic10editor.editor;
if (settings.keyboard === 'ace') {
editor.setOption('keyboardHandler', null);
} else {
@@ -96,7 +92,7 @@ class IC10EditorUI {
}
reCalcEditorSize() {
const editor = this.ic10editor.aceEditor;
const editor = this.ic10editor.editor;
const navBar = document.getElementById("navBar");
const statusBarContainer = document.getElementById("statusBarContainer");

View File

@@ -1,71 +1,87 @@
import { IC10Editor, setupLspWorker } from "./editor";
import { Session } from './session';
import { IC10Editor } from "./editor";
import { Session } from "./session";
import { VirtualMachine } from "./virtual_machine";
import { docReady, openFile, saveFile } from "./utils";
// import { makeRequest } from "./utils";
declare global {
interface Window { App: App }
interface Window {
App: App;
}
}
type App = {
editorSettings: { fontSize: number, relativeLineNumbers: boolean }; editor: IC10Editor, vm: VirtualMachine, session: Session
}
editorSettings: { fontSize: number; relativeLineNumbers: boolean };
editor: IC10Editor;
vm: VirtualMachine;
session: Session;
};
export const App: App = {
editor: null,
vm: null,
session: new Session(),
editorSettings: { fontSize: 16, relativeLineNumbers: false }
editorSettings: { fontSize: 16, relativeLineNumbers: false },
};
window.App = App;
// const dbPromise = makeRequest({ method: "GET", url: "/data/database.json"});
// const dbPromise = fetch("/data/database.json").then(resp => resp.json());
const dbPromise = import("../../data/database.json")
const dbPromise = import("../../data/database.json");
docReady(() => {
App.vm = new VirtualMachine();
dbPromise.then(db => App.vm.setupDeviceDatabase(db))
dbPromise.then((db) => App.vm.setupDeviceDatabase(db));
const init_session_id = App.vm.devices.get(0).id;
App.editor = new IC10Editor(init_session_id);
setupLspWorker().then((worker) => {
App.editor.setupLsp(worker);
})
// App.editor = new IC10Editor(init_session_id);
// setupLspWorker().then((worker) => {
// App.editor.setupLsp(worker);
// });
// Menu
document.getElementById("mainMenuShare").addEventListener('click', (_event) => {
const link = document.getElementById("shareLinkText") as HTMLInputElement;
link.setAttribute('value', window.location.href);
link.setSelectionRange(0, 0);
}, { capture: true });
document.getElementById("shareLinkCopyButton").addEventListener('click', (event) => {
event.preventDefault();
const link = document.getElementById("shareLinkText") as HTMLInputElement;
link.select();
link.setSelectionRange(0, 99999);
navigator.clipboard.writeText(link.value);
}, { capture: true });
document.getElementById("mainMenuOpenFile").addEventListener('click', (_event) => {
openFile(App.editor.aceEditor);
}, { capture: true });
document.getElementById("mainMenuSaveAs").addEventListener('click', (_event) => {
saveFile(App.editor.aceEditor.getSession().getValue())
}, { capture: true });
document.getElementById("mainMenuKeyboardShortcuts").addEventListener('click', (_event) => {
App.editor.aceEditor.execCommand("showKeyboardShortcuts");
}, { capture: true });
document.getElementById("mainMenuShare").addEventListener(
"click",
(_event) => {
const link = document.getElementById("shareLinkText") as HTMLInputElement;
link.setAttribute("value", window.location.href);
link.setSelectionRange(0, 0);
},
{ capture: true },
);
document.getElementById("shareLinkCopyButton").addEventListener(
"click",
(event) => {
event.preventDefault();
const link = document.getElementById("shareLinkText") as HTMLInputElement;
link.select();
link.setSelectionRange(0, 99999);
navigator.clipboard.writeText(link.value);
},
{ capture: true },
);
document.getElementById("mainMenuOpenFile").addEventListener(
"click",
(_event) => {
openFile(App.editor.editor);
},
{ capture: true },
);
document.getElementById("mainMenuSaveAs").addEventListener(
"click",
(_event) => {
saveFile(App.editor.editor.getSession().getValue());
},
{ capture: true },
);
document.getElementById("mainMenuKeyboardShortcuts").addEventListener(
"click",
(_event) => {
App.editor.editor.execCommand("showKeyboardShortcuts");
},
{ capture: true },
);
});

View File

@@ -1,10 +1,10 @@
import '@popperjs/core';
import '../scss/styles.scss';
import { Dropdown, Modal } from 'bootstrap';
import "@popperjs/core";
import "../scss/styles.scss";
import { Dropdown, Modal } from "bootstrap";
import "./app";
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `main.js` file does the single async import, so
// that no one else needs to worry about it again.
import("./index")
.catch(e => console.error("Error importing `index.ts`:", e));
// import("./index")
// .catch(e => console.error("Error importing `index.ts`:", e));

View File

@@ -3,20 +3,20 @@ const demoCode = `# Highlighting Demo
# This is a comment
# Hover a define id anywhere to see it's definition
define a_def 10
define a_def 10
# Hover HASH("String")'s to see computed crc32
# hover here vvvvvvvvvvvvvvvv
define a_hash HASH("This is a String")
define a_hash HASH("This is a String")
# hover over an alias anywhere in the code
# to see it's definition
alias a_var r0
alias a_var r0
alias a_device d0
# instructions have Auto Completion,
# instructions have Auto Completion,
# numeric logic types are identified on hover
s db 12 0
s db 12 0
# ^^
# hover here
@@ -42,9 +42,9 @@ move r0 HASH("AccessCardBlack")
push r0
beqzal r1 test
# -2045627372 is the crc32 hash of a SolarPanel,
# -2045627372 is the crc32 hash of a SolarPanel,
# hover it to see the documentation!
# vvvvvvvvvv
# vvvvvvvvvv
move r1 -2045627372
jal test
move r1 $FF
@@ -65,7 +65,7 @@ interface SessionCbFn {
(param: Session): void;
}
class Session {
class Session extends EventTarget {
_programs: Map<number, string>;
_onLoadCallbacks: SessionCbFn[];
_activeSession: number;
@@ -74,6 +74,7 @@ class Session {
_activeLine: number;
private _save_timeout: ReturnType<typeof setTimeout>;
constructor() {
super();
this._programs = new Map();
this._save_timeout = null;
this._onLoadCallbacks = [];

View File

@@ -112,7 +112,7 @@ class VirtualMachine {
const ic = this.activeIC;
if (ic) {
try {
ic.step();
ic.step(false);
} catch (e) {
console.log(e);
}