From c86797be002eae7d9c52fb0aea67d176c4004544 Mon Sep 17 00:00:00 2001 From: robalb <11277482+robalb@users.noreply.github.com> Date: Sun, 20 Oct 2024 18:41:32 +0200 Subject: [PATCH 1/8] fixed integration of ARIA tabelement with svelte, with proper garbage collection --- svelte_blinkenweb/src/MobileLayout.svelte | 139 +-------------------- svelte_blinkenweb/src/core/ARIA.ts | 145 ++++++++++++++++++++++ 2 files changed, 149 insertions(+), 135 deletions(-) create mode 100644 svelte_blinkenweb/src/core/ARIA.ts diff --git a/svelte_blinkenweb/src/MobileLayout.svelte b/svelte_blinkenweb/src/MobileLayout.svelte index def1126..a7cd5a6 100644 --- a/svelte_blinkenweb/src/MobileLayout.svelte +++ b/svelte_blinkenweb/src/MobileLayout.svelte @@ -6,152 +6,21 @@ import Registers from './components/Registers.svelte'; import Disassembler from './components/Disassembler.svelte'; import Terminal from './components/Terminal.svelte'; import Controls from './components/Controls.svelte'; +import {TabsAutomatic} from './core/ARIA' import {blinkStore, state} from './core/blinkSvelte' let blink = blinkStore.getInstance() -/* - * This content is licensed according to the W3C Software License at - * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document - * - * File: tabs-automatic.js - * - * Desc: Tablist widget that implements ARIA Authoring Practices - */ - -class TabsAutomatic { - tablistNode: any; - tabs: any; - firstTab: any; - lastTab: any; - tabpanels: any; - - constructor(groupNode: any) { - this.tablistNode = groupNode; - - this.tabs = []; - - this.firstTab = null; - this.lastTab = null; - - this.tabs = Array.from(this.tablistNode.querySelectorAll('[role=tab]')); - this.tabpanels = []; - - for (var i = 0; i < this.tabs.length; i += 1) { - var tab = this.tabs[i]; - var tabpanel = document.getElementById(tab.getAttribute('aria-controls')); - - tab.tabIndex = -1; - tab.setAttribute('aria-selected', 'false'); - this.tabpanels.push(tabpanel); - - tab.addEventListener('keydown', this.onKeydown.bind(this)); - tab.addEventListener('click', this.onClick.bind(this)); - - if (!this.firstTab) { - this.firstTab = tab; - } - this.lastTab = tab; - } - - this.setSelectedTab(this.firstTab, false); - } - - setSelectedTab(currentTab:any, setFocus=true) { - if (typeof setFocus !== 'boolean') { - setFocus = true; - } - for (var i = 0; i < this.tabs.length; i += 1) { - var tab = this.tabs[i]; - if (currentTab === tab) { - tab.setAttribute('aria-selected', 'true'); - tab.removeAttribute('tabindex'); - this.tabpanels[i].classList.remove('is-hidden'); - if (setFocus) { - tab.focus(); - } - } else { - tab.setAttribute('aria-selected', 'false'); - tab.tabIndex = -1; - this.tabpanels[i].classList.add('is-hidden'); - } - } - } - - setSelectedToPreviousTab(currentTab) { - var index; - - if (currentTab === this.firstTab) { - this.setSelectedTab(this.lastTab); - } else { - index = this.tabs.indexOf(currentTab); - this.setSelectedTab(this.tabs[index - 1]); - } - } - - setSelectedToNextTab(currentTab) { - var index; - - if (currentTab === this.lastTab) { - this.setSelectedTab(this.firstTab); - } else { - index = this.tabs.indexOf(currentTab); - this.setSelectedTab(this.tabs[index + 1]); - } - } - - /* EVENT HANDLERS */ - - onKeydown(event) { - var tgt = event.currentTarget, - flag = false; - - switch (event.key) { - case 'ArrowLeft': - this.setSelectedToPreviousTab(tgt); - flag = true; - break; - - case 'ArrowRight': - this.setSelectedToNextTab(tgt); - flag = true; - break; - - case 'Home': - this.setSelectedTab(this.firstTab); - flag = true; - break; - - case 'End': - this.setSelectedTab(this.lastTab); - flag = true; - break; - - default: - break; - } - - if (flag) { - event.stopPropagation(); - event.preventDefault(); - } - } - - onClick(event) { - this.setSelectedTab(event.currentTarget); - } -} - // Initialize tablist function initTabARIA(node){ console.log(node) - new TabsAutomatic(node); + let t = new TabsAutomatic(node); return{ update(){ - }, - destroy(){ + destroy: ()=>{ + t.release(); } } } diff --git a/svelte_blinkenweb/src/core/ARIA.ts b/svelte_blinkenweb/src/core/ARIA.ts new file mode 100644 index 0000000..b487982 --- /dev/null +++ b/svelte_blinkenweb/src/core/ARIA.ts @@ -0,0 +1,145 @@ + + +/* + * This content is licensed according to the W3C Software License at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * + * File: tabs-automatic.js + * https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-automatic/ + * + * Desc: Tablist widget that implements ARIA Authoring Practices + */ +export class TabsAutomatic { + tablistNode: any; + tabs: any; + firstTab: any; + lastTab: any; + tabpanels: any; + + constructor(groupNode: any) { + this.tablistNode = groupNode; + + this.tabs = []; + + this.firstTab = null; + this.lastTab = null; + + this.tabs = Array.from(this.tablistNode.querySelectorAll('[role=tab]')); + this.tabpanels = []; + + for (var i = 0; i < this.tabs.length; i += 1) { + var tab = this.tabs[i]; + var tabpanel = document.getElementById(tab.getAttribute('aria-controls')); + + tab.tabIndex = -1; + tab.setAttribute('aria-selected', 'false'); + this.tabpanels.push(tabpanel); + + tab.addEventListener('keydown', this.onKeydown.bind(this)); + tab.addEventListener('click', this.onClick.bind(this)); + + if (!this.firstTab) { + this.firstTab = tab; + } + this.lastTab = tab; + } + + this.setSelectedTab(this.firstTab, false); + } + + /* + * call this on class destruction + */ + release(){ + for (var i = 0; i < this.tabs.length; i += 1) { + var tab = this.tabs[i]; + tab.removeEventListener('keydown', this.onKeydown.bind(this)); + tab.removeEventListener('click', this.onClick.bind(this)); + } + } + + setSelectedTab(currentTab:any, setFocus=true) { + if (typeof setFocus !== 'boolean') { + setFocus = true; + } + for (var i = 0; i < this.tabs.length; i += 1) { + var tab = this.tabs[i]; + if (currentTab === tab) { + tab.setAttribute('aria-selected', 'true'); + tab.removeAttribute('tabindex'); + this.tabpanels[i].classList.remove('is-hidden'); + if (setFocus) { + tab.focus(); + } + } else { + tab.setAttribute('aria-selected', 'false'); + tab.tabIndex = -1; + this.tabpanels[i].classList.add('is-hidden'); + } + } + } + + setSelectedToPreviousTab(currentTab) { + var index; + + if (currentTab === this.firstTab) { + this.setSelectedTab(this.lastTab); + } else { + index = this.tabs.indexOf(currentTab); + this.setSelectedTab(this.tabs[index - 1]); + } + } + + setSelectedToNextTab(currentTab) { + var index; + + if (currentTab === this.lastTab) { + this.setSelectedTab(this.firstTab); + } else { + index = this.tabs.indexOf(currentTab); + this.setSelectedTab(this.tabs[index + 1]); + } + } + + /* EVENT HANDLERS */ + onKeydown(event) { + var tgt = event.currentTarget, + flag = false; + + switch (event.key) { + case 'ArrowLeft': + this.setSelectedToPreviousTab(tgt); + flag = true; + break; + + case 'ArrowRight': + this.setSelectedToNextTab(tgt); + flag = true; + break; + + case 'Home': + this.setSelectedTab(this.firstTab); + flag = true; + break; + + case 'End': + this.setSelectedTab(this.lastTab); + flag = true; + break; + + default: + break; + } + + if (flag) { + event.stopPropagation(); + event.preventDefault(); + } + } + + onClick(event) { + this.setSelectedTab(event.currentTarget); + } +} + + From 2f70c4fe102ea5d84646df5f556cdd93f40c19a0 Mon Sep 17 00:00:00 2001 From: robalb <11277482+robalb@users.noreply.github.com> Date: Sun, 20 Oct 2024 20:15:47 +0200 Subject: [PATCH 2/8] fixed other issues with the disassembly manual rendering, adedd disass fail design --- .../src/components/Disassembler.svelte | 60 +++++++++++++------ svelte_blinkenweb/src/styles/style.css | 7 ++- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/svelte_blinkenweb/src/components/Disassembler.svelte b/svelte_blinkenweb/src/components/Disassembler.svelte index d4ccbcf..bbe19bb 100644 --- a/svelte_blinkenweb/src/components/Disassembler.svelte +++ b/svelte_blinkenweb/src/components/Disassembler.svelte @@ -1,21 +1,12 @@ -
- - +
+ {#if disassebly_fail} +
+

Disassembly failed

+
+ {/if} +
+ {#each Array(100) as _} @@ -118,9 +125,28 @@ $: $manual_render && updateDis(); {/each} -
0000000
+
diff --git a/svelte_blinkenweb/src/styles/style.css b/svelte_blinkenweb/src/styles/style.css index 7d50e1e..90ceed5 100644 --- a/svelte_blinkenweb/src/styles/style.css +++ b/svelte_blinkenweb/src/styles/style.css @@ -107,9 +107,10 @@ --theme-dislabel-fg: var(--color-orange); --theme-dis-current-bg: rgba(255,255,255,0.1); --theme-dis-current-border: gray; - - - + --theme-dis-fail-stripebg1: var(--color-gray-t); + --theme-dis-fail-stripebg2: transparent; + --theme-dis-fail-boxborder: var(--color-orange); + --theme-dis-fail-boxbg: var(--theme-bg); } From ac4730ff86f5cd0d9dde7f0715bc1b85b9c20963 Mon Sep 17 00:00:00 2001 From: robalb <11277482+robalb@users.noreply.github.com> Date: Mon, 21 Oct 2024 22:56:49 +0200 Subject: [PATCH 3/8] cleaned styles --- svelte_blinkenweb/src/MobileLayout.svelte | 43 ++--------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/svelte_blinkenweb/src/MobileLayout.svelte b/svelte_blinkenweb/src/MobileLayout.svelte index a7cd5a6..d8a3a07 100644 --- a/svelte_blinkenweb/src/MobileLayout.svelte +++ b/svelte_blinkenweb/src/MobileLayout.svelte @@ -86,13 +86,6 @@ $: showEditor = ( /* border: 1px solid var(--theme-panel-border); */ } - .controls{ - /* overflow: auto; */ - /* height: 100%; */ - /*this is cool the first time you see it, then super annoying */ - /* scroll-behavior: smooth; */ - } - .tabs { height: 100%; overflow: auto; @@ -112,25 +105,14 @@ $: showEditor = ( display:flex; align-items:center; justify-content:center; - /* display: inline-block; */ - /* z-index: 2; */ + margin: 0; outline: none; overflow: hidden; text-align: left; cursor: pointer; - /* font-weight: bold; */ - /* max-width: 22%; */ - /* top: 2px; */ - /* margin-top: 4px; */ - /* padding: 3px 3px 4px; */ - /* border: 1px solid hsl(219deg 1% 72%); */ - /* border-bottom: 2px solid hsl(219deg 1% 72%); */ - /* border-radius: 5px 5px 0 0; */ - /* background: hsl(220deg 20% 94%); */ - - background-color: transparent; + background-color: var(--theme-bg); height: 3rem; flex-grow: 1; @@ -145,14 +127,7 @@ $: showEditor = ( } [role="tab"][aria-selected="true"] { - /* padding: 2px 2px 4px; */ - /* margin-top: 0; */ - /* border-width: 2px; */ - /* border-top-width: 6px; */ - /* border-bottom-color: hsl(220deg 43% 99%); */ - /* background: hsl(220deg 43% 99%); */ - border-top-color: transparent; - background-color: var(--theme-bg); + background-color: transparent; border-bottom: 6px solid var(--theme-focus); } @@ -166,14 +141,6 @@ $: showEditor = ( padding: 4px 6px; } - [role="tab"]:hover span.focus, - [role="tab"]:focus span.focus, - [role="tab"]:active span.focus { - /* padding: 2px 4px; */ - /* border: 2px solid var(--theme-focus); */ - /* border-radius: 3px; */ - } - [role="tabpanel"] { width: 100%; height: 100%; @@ -185,10 +152,6 @@ $: showEditor = ( display: none; } - [role="tabpanel"] p { - margin: 0; - } - From 170a3729e569cc21c70f464e8cbab21923057b27 Mon Sep 17 00:00:00 2001 From: robalb <11277482+robalb@users.noreply.github.com> Date: Tue, 22 Oct 2024 00:51:43 +0200 Subject: [PATCH 4/8] added experimental file drop feature --- svelte_blinkenweb/src/App.svelte | 103 +++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/svelte_blinkenweb/src/App.svelte b/svelte_blinkenweb/src/App.svelte index cef8d7c..3cd8d82 100644 --- a/svelte_blinkenweb/src/App.svelte +++ b/svelte_blinkenweb/src/App.svelte @@ -3,19 +3,122 @@ import './styles/style.css'; import DesktopLayout from './DesktopLayout.svelte'; import MobileLayout from './MobileLayout.svelte'; +import {blinkStore} from './core/blinkSvelte' +let blink = blinkStore.getInstance() + +//make the blink wrapper accessible to the developer tools +window['blink'] = blink; + let innerWidth = 0; let breakpoints = { mobile: 640 } +let dragDecoration = false; +let timer = null; + +function handleDragover(e){ + e.preventDefault(); + dragDecoration = true; + clearTimeout(timer) + timer = setTimeout(()=>{ + dragDecoration = false; + }, 2000) +} + +export const fileToArrayBuffer = (blob: Blob) => { + return new Promise((resolve) => { + const reader = new FileReader() + reader.onloadend = () => resolve(reader.result) + reader.readAsArrayBuffer(blob) + }) +} + +async function handleDrop(e){ + e.preventDefault(); + console.log("drop") + dragDecoration = false; + + let firstfile: any; + if (e.dataTransfer.items) { + firstfile = [...e.dataTransfer.items].find((item) => item.kind == "file") + } else { + firstfile = [...e.dataTransfer.files][0] + } + if (firstfile) { + const file = firstfile.getAsFile(); + let filedata = await fileToArrayBuffer(file); + blink.loadElf(filedata); + blink.starti() + } + +} + +
+{#if dragDecoration} +
+
+

Run your executable

+

Drop a statically-linked ELF here to + execute it in a sandboxed environment

+
+
+{/if} {#if innerWidth <= breakpoints.mobile} {:else} {/if} +
+ From f661649c54d7a06b2998189f3f0b0f6e54dd86ba Mon Sep 17 00:00:00 2001 From: robalb <11277482+robalb@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:13:43 +0200 Subject: [PATCH 5/8] file upload ui and ux (still WIP) --- svelte_blinkenweb/src/App.svelte | 3 +- .../src/components/Controls.svelte | 3 +- .../src/components/Editor.svelte | 70 ++++++++++++++++++- svelte_blinkenweb/src/core/blinkSvelte.js | 5 ++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/svelte_blinkenweb/src/App.svelte b/svelte_blinkenweb/src/App.svelte index 3cd8d82..2a37981 100644 --- a/svelte_blinkenweb/src/App.svelte +++ b/svelte_blinkenweb/src/App.svelte @@ -3,7 +3,7 @@ import './styles/style.css'; import DesktopLayout from './DesktopLayout.svelte'; import MobileLayout from './MobileLayout.svelte'; -import {blinkStore} from './core/blinkSvelte' +import {blinkStore, uploadedElf} from './core/blinkSvelte' let blink = blinkStore.getInstance() //make the blink wrapper accessible to the developer tools @@ -50,6 +50,7 @@ async function handleDrop(e){ let filedata = await fileToArrayBuffer(file); blink.loadElf(filedata); blink.starti() + blinkStore.setUploadedElfName(file.name) } } diff --git a/svelte_blinkenweb/src/components/Controls.svelte b/svelte_blinkenweb/src/components/Controls.svelte index ed3337f..857ace7 100644 --- a/svelte_blinkenweb/src/components/Controls.svelte +++ b/svelte_blinkenweb/src/components/Controls.svelte @@ -74,6 +74,7 @@ function handle_back(){ blink.setready() + blinkStore.setUploadedElfName("") } @@ -91,7 +92,7 @@
- {#if showEditor || !mobile} + {#if (showEditor || !mobile) && !$blinkStore.uploadedElf}