dont use innerHTML

This commit is contained in:
“chrisshank” 2024-12-09 11:51:20 -08:00
parent c3e161d2c8
commit de724dd087
8 changed files with 69 additions and 63 deletions

View File

@ -129,7 +129,7 @@ async function openFile(showPicker = true) {
try {
const text = await fileSaver.open(showPicker);
const json = JSON.parse(text || '{ "thoughts": [], "connections": [] }');
main.innerHTML = renderChainOfThought(json);
main.setHTMLUnsafe(renderChainOfThought(json));
} catch (e) {
// No file handler was persisted or the file is invalid JSON.
console.error(e);

View File

@ -1,5 +1,5 @@
// Ported from https://github.com/bitu467/record-player
import { css } from '../../src/common/tags';
import { css, html } from '../../src/common/tags';
const styles = css`
::slotted(*) {
@ -236,18 +236,17 @@ export class RecordPlayer extends HTMLElement {
const shadow = this.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets.push(styles);
shadow.innerHTML = `
<div class="player">
<div class="record">
<div class="label"></div>
</div>
<div class="tone-arm">
<div class="control"></div>
</div>
<button class="btn"></button>
<input type="range" class="slider" min="0" max="1" step="0.05" value="0.5">
</div>
<slot></slot>`;
shadow.setHTMLUnsafe(html` <div class="player">
<div class="record">
<div class="label"></div>
</div>
<div class="tone-arm">
<div class="control"></div>
</div>
<button class="btn"></button>
<input type="range" class="slider" min="0" max="1" step="0.05" value="0.5" />
</div>
<slot></slot>`);
this.#volumeInput = shadow.querySelector('input[type="range"]')!;
this.#volumeInput.addEventListener('input', this);

View File

@ -91,7 +91,7 @@ export class FolkLLM extends HTMLElement {
const stream = await this.#session.promptStreaming(this.prompt);
for await (const chunk of stream) {
this.#shadow.innerHTML = chunk;
this.#shadow.setHTMLUnsafe(chunk);
}
this.dispatchEvent(new Event('finished'));

View File

@ -258,7 +258,7 @@ export class FolkShape extends HTMLElement {
// Ideally we would creating these lazily on first focus, but the resize handlers need to be around for delegate focus to work.
// Maybe can add the first resize handler here, and lazily instantiate the rest when needed?
// I can see it becoming important at scale
this.#shadow.innerHTML = html` <button part="rotation-top-left" tabindex="-1"></button>
this.#shadow.setHTMLUnsafe(html` <button part="rotation-top-left" tabindex="-1"></button>
<button part="rotation-top-right" tabindex="-1"></button>
<button part="rotation-bottom-right" tabindex="-1"></button>
<button part="rotation-bottom-left" tabindex="-1"></button>
@ -266,7 +266,7 @@ export class FolkShape extends HTMLElement {
<button part="resize-top-right" aria-label="Resize shape from top right"></button>
<button part="resize-bottom-right" aria-label="Resize shape from bottom right"></button>
<button part="resize-bottom-left" aria-label="Resize shape from bottom left"></button>
<div><slot></slot></div>`;
<div><slot></slot></div>`);
this.#handles = Object.fromEntries(
Array.from(this.#shadow.querySelectorAll('[part]')).map((el) => [

View File

@ -46,7 +46,7 @@ export class FolkSpaceRadial extends HTMLElement {
this.#centerPoint = document.createElement('div');
this.#centerPoint.className = 'center-point';
this.#shadow.innerHTML = html` <slot></slot> `;
this.#shadow.setHTMLUnsafe(html`<slot></slot> `);
this.#shadow.appendChild(this.#centerPoint);
// Listen for changes in the slot to layout children when they change

View File

@ -1,4 +1,4 @@
import { html } from './common/tags';
import { html, css } from './common/tags';
declare global {
interface HTMLElementTagNameMap {
@ -6,6 +6,44 @@ declare global {
}
}
const styles = css`
:host {
display: block;
perspective: 1000px;
position: relative;
width: 100%;
height: 100%;
}
.space {
position: absolute;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transform-origin: center;
transition: transform 0.6s;
}
.space.rotate {
transform: rotateX(-90deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.front {
transform: rotateX(0deg);
}
.back {
transform: rotateX(90deg);
}
`;
export class FolkSpace extends HTMLElement {
static tagName = 'folk-space';
@ -14,47 +52,14 @@ export class FolkSpace extends HTMLElement {
customElements.define(this.tagName, this);
}
#shadow = this.attachShadow({ mode: 'open' });
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = html`
<style>
:host {
display: block;
perspective: 1000px;
position: relative;
width: 100%;
height: 100%;
}
.space {
position: absolute;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transform-origin: center;
transition: transform 0.6s;
}
this.#shadow.adoptedStyleSheets.push(styles);
.space.rotate {
transform: rotateX(-90deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.front {
transform: rotateX(0deg);
}
.back {
transform: rotateX(90deg);
}
</style>
this.#shadow.setHTMLUnsafe(html`
<div class="space">
<div class="face front">
<slot name="front"></slot>
@ -63,7 +68,7 @@ export class FolkSpace extends HTMLElement {
<slot name="back"></slot>
</div>
</div>
`;
`);
}
transition() {

View File

@ -1,4 +1,4 @@
import { css } from './common/tags';
import { css, html } from './common/tags';
// hardcoded column and row numbers
const styles = css`
@ -214,14 +214,14 @@ export class FolkSpreadsheet extends HTMLElement {
.join('\n')}
</style>`;
this.#shadow.innerHTML = `
this.#shadow.setHTMLUnsafe(html`
<s-header empty></s-header>
<s-columns>${columnHeaders}</s-columns>
<s-rows>${rowHeaders}</s-rows>
<s-body><slot></slot></s-body>
<textarea hidden></textarea>
${style}
`;
`);
this.#textarea = this.#shadow.querySelector('textarea')!;
}

View File

@ -1,3 +1,5 @@
import { html } from './common/tags';
interface Weather {
temperature: string;
windSpeed: string;
@ -60,12 +62,12 @@ export class FolkWeather extends HTMLElement {
#renderResults() {
if (this.#results === null) {
this.innerHTML = '';
this.setHTMLUnsafe('');
return;
}
this.innerHTML = `
this.setHTMLUnsafe(html`
<p>Temperature: ${this.#results.temperature}</p>
<p>Wind Speed: ${this.#results.windSpeed}</p>
`;
`);
}
}