Browse Source

Better design and lots of little fixes all over.

master
Zed A. Shaw 1 year ago
parent
commit
c0456f84c3
  1. 8
      sass/_variables.scss
  2. 9
      src/components/Footer.svelte
  3. 48
      src/components/Nav.svelte
  4. 8
      src/components/Sidebar.svelte
  5. 9
      src/node_modules/buttons.js
  6. 24
      src/routes/_layout.svelte
  7. 122
      src/routes/index.svelte
  8. 10
      src/service-worker.js
  9. 2
      static/css/spectre-exp.min.css
  10. 2
      static/css/spectre.min.css

8
sass/_variables.scss

@ -37,9 +37,9 @@ $bg-color-dark: darken($bg-color, 10%) !default;
$bg-color-light: lighten($bg-color, 10%) !default;
// Control colors
$success-color: #32b643 !default;
$warning-color: $green !default;
$error-color: #e85600 !default;
$success-color: $green !default;
$warning-color: $yellow !default;
$error-color: $red !default;
// Other colors
$code-color: $green !default;
@ -74,7 +74,7 @@ $unit-12: 2.4rem !default;
$unit-16: 3.2rem !default;
// Font sizes
$html-font-size: 25px !default;
$html-font-size: 16px !default;
$html-line-height: 1.5 !default;
$font-size: 1rem !default;
$font-size-sm: .9rem !default;

9
src/components/Footer.svelte

@ -7,7 +7,7 @@
#footer {
border-top: 1px solid $primary-color;
background-color: $gray-color-light;
background-color: $gray-color;
}
#right-column {
@ -17,7 +17,8 @@
#footer .panel {
border: 0px;
border-radius: 0px;
font-size: $font-size-sm;
font-size: 20px !important;
text-shadow: 2px 2px $gray-color-dark;
}
</style>
@ -33,7 +34,7 @@
</div>
<div class="column col-3" id="right-column">
<a alt="Twitter @lzsthw" aria-label="Twitter @lzsthw" rel="external" href="https://twitter.com/lzsthw"><Icon size="48" name="twitter" /></a>
<a alt="The git repository" aria-label="The git repository" rel="external" href="https://git.learnjsthehardway.com/zedshaw/buttons-computer"><Icon size="48" name="code" /></a>
<a alt="Twitter @lzsthw" aria-label="Twitter @lzsthw" rel="external" href="https://twitter.com/lzsthw"><Icon size="48" name="twitter" light={true} /></a>
<a alt="The git repository" aria-label="The git repository" rel="external" href="https://git.learnjsthehardway.com/zedshaw/buttons-computer"><Icon size="48" name="code" light={true} /></a>
</div>
</div>

48
src/components/Nav.svelte

@ -0,0 +1,48 @@
<script>
export let segment;
import { goto } from '@sapper/app';
import Icon from './Icon.svelte';
</script>
<style lang="scss">
@import "sass/_variables";
#logo {
font-size: 24px;
text-shadow: 2px 2px $gray-color-dark;
}
.menu-item .active {
background-color: $red;
}
.btn {
background-color: $red !important;
margin-left: 4px;
border: 1px solid $black;
height: 40px;
}
.navbar {
background-color: $gray-color;
min-height: 50px;
}
</style>
<header class="navbar">
<section class="navbar-section">
<a class="navbar-brand mr-2" href="/">
<div id="logo">BUTTONS</div>
</a>
</section>
<section class="navbar-section">
<a data-testid='nav-home-icon' rel="prefetch" class:btn-link="{ segment != undefined }" class="btn" href="/" alt="Home" aria-label="Home">
<Icon name="home" size="32" tooltip="Home" tooltip_bottom={true} light={true}/>
</a>
<a data-testid='nav-blog-icon' rel="external" class:btn-link="{ segment != 'blog' }" class="btn" href="https://learnjsthehardway.com/blog" alt="Read the blog" aria-label="Read the blog">
<Icon name="book-open" size="32" tooltip="Blog" tooltip_bottom={true} light={true} />
</a>
</section>
</header>

8
src/components/Sidebar.svelte

@ -1,7 +1,8 @@
<script>
import { ButtonMachine } from 'buttons';
let ops = ButtonMachine.operations();
const ops = ButtonMachine.operations();
const registers = ButtonMachine.register_names();
</script>
@ -16,5 +17,10 @@ OPERATIONS:
{#each ops as op}
{ op + '\n'}
{/each}
REGISTERS:
{#each registers as reg}
{ reg + '\n'}
{/each}
</code>
</pre>

9
src/node_modules/buttons.js

@ -27,6 +27,11 @@ class ButtonMachine {
return test;
}
/* Need to use a function because @babel/plugin-proposal-class-properties */
static register_names() {
return ['AX', 'BX', 'CX', 'DX'];
}
static operations() {
return Object.getOwnPropertyNames(ButtonMachine.prototype)
.filter(x => x.startsWith('op_'))
@ -137,11 +142,15 @@ class ButtonMachine {
}
op_STOR(reg) {
if(!this.assert(!reg.includes(reg), `Register ${reg} is not valid. Use ${ButtonMachine.registers_names()}`)) return;
this.registers[reg] = this.stack_top;
this.next();
}
op_RSTOR(reg) {
if(!this.assert(!reg.includes(reg), `Register ${reg} is not valid. Use ${ButtonMachine.registers_names()}`)) return;
let val = this.registers[reg];
this.assert(val !== undefined, `Invalid register ${reg}`);

24
src/routes/_layout.svelte

@ -1,10 +1,15 @@
<script>
import Footer from '../components/Footer.svelte';
import Nav from '../components/Nav.svelte';
import Sidebar from '../components/Sidebar.svelte';
export let segment;
</script>
<style>
#main {
<style lang="scss">
@import "sass/_variables";
#main {
display: flex;
flex: 1 0 auto;
min-height: 100vh;
@ -12,16 +17,18 @@
padding-left: 0px;
padding-right: 0px;
min-width: 340px;
}
border: 1px solid darken($green, 10%) !important;
}
#main_content {
#main_content {
flex-grow: 1;
}
}
</style>
<div class="container grid-xl full-width" id="main">
<div class="container grid-lg" id="main">
<div class="columns" id="nav">
<div class="column col-mx-auto">
<Nav {segment} />
</div>
</div>
@ -29,15 +36,12 @@
<div class="columns">
<div class="column col-mx-auto">
<div class="off-canvas">
<a class="off-canvas-toggle btn btn-primary btn-action" href="#sidebar-id">
?¿
</a>
<div id="sidebar-id" class="off-canvas-sidebar">
<Sidebar />
</div>
<a class="off-canvas-overlay" href="#close"></a>
<a alt="Close sidebar" aria-label="Close sidebar" class="off-canvas-overlay" href="#close">&nbsp;</a>
<div class="off-canvas-content">
<slot></slot>

122
src/routes/index.svelte

@ -65,44 +65,38 @@
<style lang="scss">
@import "sass/_variables";
#status-panel {
font-size: 14px;
}
.active-line {
background-color: $warning-color !important;
background-color: $green !important;
}
.empty-data {
width: 100%;
background-color: lighten($primary-color, 40%);
}
.off-canvas-toggle {
position: unset;
z-index: unset;
top: unset;
left: unset;
display: unset;
transition: unset;
padding: 5px;
}
</style>
<div class="container grid-xl" id="content" data-testid="buttons-page">
<div class="container grid-lg" id="content" data-testid="buttons-page">
<div class="columns">
<div class="column col-12">
<table class="table">
<thead>
<tr>
<th>IP</th>
<th>TICK</th>
<th>HALT</th>
<th>ERROR</th>
</tr>
</thead>
<tbody>
<tr class="active">
<td>{ machine.ip }</td>
<td>{ machine.tick }</td>
<td>{ machine.halted }</td>
<td>{ machine.error }</td>
</tr>
</tbody>
</table>
</div>
</div>
<br/>
<div class="column col-4 col-sm-12 col-md-12 col-xs-12">
<a alt="Open/Close help sidebar" aria-label="Open/Close help sidebar" class="off-canvas-toggle btn btn-primary btn-action" href="#sidebar-id">
?¿
</a>
<div class="columns">
<div class="column col-6">
<button class="btn btn-primary" on:click={ run_machine }>
<Icon code="►" tooltip="Run it" tooltip_right={ true } light={ true }/>
</button>
@ -113,19 +107,19 @@
<Icon code="■" tooltip="Reset" light={ true }/>
</button>
<div class="divider"></div>
<div class="divider"></div>
{#each code as [op, data], i}
<div class="input-group" class:has-error={ has_error }>
<div class="input-group">
{#if has_error && machine.error_line == i}
<Icon name="alert-triangle" color="red" />
{:else}
{i}:
{/if}
<button class:active-line={ machine.ip == i }
on:click={ () => change_op(i, +1) }
on:contextmenu|preventDefault={ () => change_op(i, -1) }
class="btn btn-primary input-group-btn">{op}</button>
<button class:active-line={ machine.ip == i }
on:click={ () => change_op(i, +1) }
on:contextmenu|preventDefault={ () => change_op(i, -1) }
class="btn btn-primary input-group-btn">{op}</button>
{#if op_has_data(op)}
{#if op === 'STOR' || op === 'RSTOR' || op == 'HALT'}
@ -150,12 +144,31 @@
</div>
{/each}
</div>
<div class="column col-2">
<div class="column col-8 col-sm-12 col-md-12 col-xs-12" id="status-panel">
<table class="table">
<thead>
<tr>
<th>IP</th>
<th>TICK</th>
<th>HALT</th>
<th>ERROR</th>
</tr>
</thead>
<tbody>
<tr class="active">
<td>{ machine.ip }</td>
<td>{ machine.tick }</td>
<td>{ machine.halted }</td>
<td>{ machine.error }</td>
</tr>
</tbody>
</table>
<table class="table"> <thead>
<tr>
<th>STACK</th>
</tr>
</thead>
<tr>
<th>STACK</th>
</tr>
</thead>
{#each machine.stack as datum, i}
<tr>
@ -163,24 +176,23 @@
</tr>
{/each}
</table>
</div>
<div class="column col-4">
<table class="table">
<thead>
<tr>
<th>REGISTER</th>
<th>VALUE</th>
</tr>
</thead>
<tbody>
{#each machine.register_entries as [name, value] }
<tr class="active">
<td>{ name }</td>
<td>{ value }</td>
</tr>
{/each}
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th>REGISTER</th>
<th>VALUE</th>
</tr>
</thead>
<tbody>
{#each machine.register_entries as [name, value] }
<tr class="active">
<td>{ name }</td>
<td>{ value }</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>

10
src/service-worker.js

@ -7,6 +7,8 @@ const ASSETS = `cache${timestamp}`;
const to_cache = shell.concat(files);
const cached = new Set(to_cache);
self.skipWaiting();
self.addEventListener('install', event => {
event.waitUntil(
caches
@ -31,6 +33,8 @@ self.addEventListener('activate', event => {
);
});
if(false) {
self.addEventListener('fetch', event => {
if (event.request.method !== 'GET' || event.request.headers.has('range')) return;
@ -51,12 +55,10 @@ self.addEventListener('fetch', event => {
// for pages, you might want to serve a shell `service-worker-index.html` file,
// which Sapper has generated for you. It's not right for every
// app, but if it's right for yours then uncomment this section
/*
if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
event.respondWith(caches.match('/service-worker-index.html'));
return;
}
*/
if (event.request.cache === 'only-if-cached') return;
@ -69,7 +71,7 @@ self.addEventListener('fetch', event => {
.then(async cache => {
try {
const response = await fetch(event.request, {credentials: 'same-origin'});
// cache.put(event.request, response.clone());
cache.put(event.request, response.clone());
return response;
} catch(err) {
const response = await cache.match(event.request);
@ -80,3 +82,5 @@ self.addEventListener('fetch', event => {
})
);
});
}

2
static/css/spectre-exp.min.css

File diff suppressed because one or more lines are too long

2
static/css/spectre.min.css

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save