2025-01-17 20:05:21 +00:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
2025-01-17 21:01:31 +00:00
|
|
|
<title>BinCode</title>
|
2025-01-18 20:34:54 +00:00
|
|
|
<link rel="icon" type="image/png" href="./logo/favicon-96x96.png" sizes="96x96" />
|
|
|
|
<link rel="icon" type="image/svg+xml" href="./logo/favicon.svg" />
|
|
|
|
<link rel="shortcut icon" href="./logo/favicon.ico" />
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
|
|
|
2025-01-17 20:05:21 +00:00
|
|
|
<link rel="stylesheet" href="/style.css" />
|
2025-01-18 20:34:54 +00:00
|
|
|
<link rel="stylesheet" href="./font.css">
|
2025-01-17 20:05:21 +00:00
|
|
|
<!-- Prismjs css -->
|
|
|
|
<link rel="stylesheet" href="./libraries/prism/theme/prism.min.css" />
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="app">
|
|
|
|
<nav>
|
|
|
|
<div class="brand">BinCode</div>
|
|
|
|
<div class="title-input" v-if="token">
|
|
|
|
<input type="text" v-model="title" placeholder="Snippet title" />
|
|
|
|
</div>
|
2025-01-18 17:20:03 +00:00
|
|
|
<div class="toggle-container">
|
2025-01-17 20:05:21 +00:00
|
|
|
<button class="toggle-icon" @click="toggleEditor">
|
2025-01-18 17:20:03 +00:00
|
|
|
<span v-html="showEditor ? extraIcons[0].visible : extraIcons[1].hidden"></span>
|
|
|
|
<span>editor</span>
|
2025-01-17 20:05:21 +00:00
|
|
|
</button>
|
|
|
|
|
|
|
|
<button class="toggle-icon" @click="togglePreview">
|
2025-01-18 17:20:03 +00:00
|
|
|
<span v-html="showPreview ? extraIcons[0].visible : extraIcons[1].hidden"></span>
|
|
|
|
<span>preview</span>
|
2025-01-17 20:05:21 +00:00
|
|
|
</button>
|
2025-01-18 20:34:54 +00:00
|
|
|
|
|
|
|
<button class="toggle-icon" @click="toggleConsole">
|
|
|
|
<span v-html="showConsole ? extraIcons[2].console : extraIcons[2].console"></span>
|
|
|
|
<span>console</span>
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button
|
|
|
|
class="toggle-icon"
|
|
|
|
@click="toggleExecution"
|
|
|
|
:class="{ 'toggle-active': isExecutionPaused }"
|
|
|
|
>
|
|
|
|
<span v-html="isExecutionPaused ? playIcon : pauseIcon"></span>
|
|
|
|
<span>{{ isExecutionPaused ? 'Resume' : 'Pause' }}</span>
|
|
|
|
</button>
|
2025-01-17 20:05:21 +00:00
|
|
|
</div>
|
|
|
|
<div class="nav-actions">
|
|
|
|
<div class="auth-buttons" v-if="!token">
|
|
|
|
<button @click="showLogin = true">Login</button>
|
|
|
|
</div>
|
|
|
|
<div class="user-menu" v-else>
|
|
|
|
<button @click="saveSnippet" class="primary">Save</button>
|
|
|
|
<button @click="logout">Logout</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
<div class="editor-container">
|
|
|
|
<div
|
|
|
|
class="editor-group"
|
|
|
|
v-show="showEditor"
|
|
|
|
:style="{ width: editorWidth }"
|
|
|
|
>
|
|
|
|
<!-- Tab bar -->
|
|
|
|
<div class="tab-bar">
|
|
|
|
<button
|
|
|
|
v-for="tab in tabs"
|
|
|
|
:key="tab.id"
|
|
|
|
class="tab"
|
|
|
|
:class="{ active: activeTab === tab.id }"
|
|
|
|
@click="switchTab(tab.id)"
|
|
|
|
>
|
2025-01-18 17:20:03 +00:00
|
|
|
<svg class="tab-icon" v-html="tab.icon"></svg>
|
2025-01-17 20:05:21 +00:00
|
|
|
{{ tab.label }}
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Editor content -->
|
|
|
|
<div class="editor-content">
|
|
|
|
<textarea
|
|
|
|
:value="currentCode"
|
|
|
|
@input="handleInput"
|
2025-01-18 20:34:54 +00:00
|
|
|
@scroll="handleScroll"
|
2025-01-17 20:05:21 +00:00
|
|
|
@keydown="handleKeydown"
|
|
|
|
:class="{ 'active-editor': true }"
|
|
|
|
spellcheck="false"
|
|
|
|
autocomplete="off"
|
|
|
|
:placeholder="'Enter your ' + activeTab.toUpperCase() + ' code here...'"
|
|
|
|
></textarea>
|
|
|
|
<pre
|
|
|
|
class="editor-highlight"
|
|
|
|
aria-hidden="true"
|
|
|
|
><code v-html="highlightedCode[activeTab]"></code></pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
class="preview"
|
|
|
|
:style="{ width: previewWidth }"
|
|
|
|
v-show="showPreview"
|
|
|
|
>
|
|
|
|
<iframe id="preview-frame"></iframe>
|
|
|
|
</div>
|
2025-01-18 20:34:54 +00:00
|
|
|
|
|
|
|
</div>
|
2025-01-17 20:05:21 +00:00
|
|
|
|
|
|
|
<!-- Share Modal -->
|
|
|
|
<div
|
|
|
|
class="modal"
|
|
|
|
v-if="showShareModal"
|
|
|
|
@click.self="showShareModal = false"
|
|
|
|
>
|
|
|
|
<div class="modal-content">
|
|
|
|
<h2>Share Snippet</h2>
|
|
|
|
<div class="share-url">
|
|
|
|
<input type="text" :value="shareUrl" readonly ref="shareUrlInput" />
|
|
|
|
<button @click="copyShareUrl" class="primary">Copy</button>
|
|
|
|
</div>
|
|
|
|
<button class="close" @click="showShareModal = false">×</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Login Modal -->
|
|
|
|
<div class="modal" v-if="showLogin" @click.self="showLogin = false">
|
|
|
|
<div class="modal-content">
|
|
|
|
<h2>Login</h2>
|
|
|
|
<form @submit.prevent="login">
|
|
|
|
<input
|
|
|
|
type="email"
|
|
|
|
v-model="loginEmail"
|
|
|
|
placeholder="Email"
|
|
|
|
required
|
|
|
|
/>
|
|
|
|
<input
|
|
|
|
type="password"
|
|
|
|
v-model="loginPassword"
|
|
|
|
placeholder="Password"
|
|
|
|
required
|
|
|
|
/>
|
|
|
|
<button type="submit" class="primary">Login</button>
|
|
|
|
</form>
|
|
|
|
<button class="close" @click="showLogin = false">×</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- use`_dev` or `_prod` lib for vuejs based on env -->
|
|
|
|
<script src="./libraries/vue/vuejs_3.5.13_prod.js"></script>
|
|
|
|
|
|
|
|
<!-- Prismjs -->
|
|
|
|
<script src="./libraries/prism/prism.min.js"></script>
|
|
|
|
<script src="./libraries/prism/prism-markup.min.js"></script>
|
|
|
|
<script src="./libraries/prism/prism-css.min.js"></script>
|
|
|
|
<script src="./libraries/prism/prism-javascript.min.js"></script>
|
|
|
|
<script src="/app.js"></script>
|
|
|
|
</body>
|
|
|
|
</html>
|