-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
56 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
layout: post | ||
title: "Minimal WebComponent to parse file selectors into bytearrays" | ||
image: /assets/img/projects/file-byte-reader.png | ||
description: > | ||
Extending the HTMLInputElement and using custom events for easy hooks | ||
toot_id: 112919231724048267 | ||
--- | ||
|
||
I'm in the process of moving the (non-wasm parts) of my web front-end for [cega](/projects/cega) over to vanilla Jasvacript WebComponents. I've liked how much it cleans up and encapsulates the logic without even needing a framework. The hooks for parsing the file into a byte array on the client-side (for passing to the wasm) were an obvious extraction point, so I pulled it out to a gist micro-project: [file-byte-reader](/projects/file-byte-reader). | ||
|
||
This hides a [lower-level abstraction with its own async, FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader). It also makes a nice real world example of extending an input tag and using custom events to give easy hooks for your WebComponents. I liked the [pattern Chris Ferdinandi was using for having a (partially) curried emit function to make dispatching your events more succinct](https://gomakethings.com/custom-events-in-web-components/), so I've added it to my practices for WebComponents going forward. | ||
|
||
```javascript | ||
//attach a listener (to an `is` applied file selector) that will get the parsed byte array: | ||
//<input is="file-byte-reader" id="file-input" type="file" | ||
//$('#file-input').addEventListener("file-byte-reader:loaded", e => YOURHANDLER(e.detail)); | ||
class FileByteReader extends HTMLInputElement { | ||
connectedCallback() { | ||
this.addEventListener('change', this.onChange); | ||
} | ||
|
||
emit (type, detail = {}) { | ||
let event = new CustomEvent(`file-byte-reader:${type}`, { | ||
bubbles: false, | ||
cancelable: false, | ||
detail: detail | ||
}); | ||
return this.dispatchEvent(event); | ||
} | ||
|
||
onChange() { | ||
if (this.files.length == 0) { return } | ||
const fileReader = new FileReader(); | ||
fileReader.addEventListener('loadend', e => this.emit('loaded', new Int8Array(fileReader.result))); | ||
fileReader.readAsArrayBuffer(this.files[0]); | ||
} | ||
} | ||
customElements.define("file-byte-reader", FileByteReader, { extends: 'input'}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
title: file-byte-reader.js | ||
caption: WebComponent to parse a file input into a bytearray | ||
description: > | ||
WebComponent for simpler parsing of a file selector input into a bytearray (like to use in wasm file processing) | ||
date: 10 Aug 2024 | ||
image: | ||
path: /assets/img/projects/file-byte-reader.png | ||
links: | ||
- title: "perma" | ||
url: https://knz.ai/projects/file-byte-reader | ||
- title: gist | ||
url: https://gist.github.com/knzai/c297fdd13739e1a844e4001142183459 | ||
--- | ||
|
||
- Language/Platform: Javascript |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.