From 1266b373615f9e393094d15404429b14fbf8825c Mon Sep 17 00:00:00 2001 From: AylenHoz Date: Wed, 8 Jan 2025 17:35:59 -0300 Subject: [PATCH 1/7] feat: add event handlers of HTML through addEventListener --- src/component.ts | 1 + src/helpers.ts | 15 +++++++++ src/templates.ts | 5 +++ src/templates/error_stack/main.ts | 53 ++++++++++++++++++++++++------- src/templates/header/main.ts | 15 ++++++++- tests/templates.spec.ts | 3 ++ 6 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/component.ts b/src/component.ts index c498772..68b1e3e 100644 --- a/src/component.ts +++ b/src/component.ts @@ -15,6 +15,7 @@ import { readFile } from 'node:fs/promises' */ export abstract class BaseComponent { declare $props: Props + eventHandlers?: string[] #cachedStyles?: string #cachedScript?: string diff --git a/src/helpers.ts b/src/helpers.ts index 6c03cc2..fbc4a79 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -71,6 +71,21 @@ export function stripAnsi(value: string) { return value.replace(ANSI_REGEX, '') } +/** + * Return line to add event handler of an element as a listener + */ +export function getAddEventListenerLine({ + id, + handler, + event = 'click', +}: { + id: string + handler: string + event?: string +}) { + return `document.getElementById("${id}").addEventListener("${event}",${handler});` +} + /** * ANSI coloring library */ diff --git a/src/templates.ts b/src/templates.ts index 2c30d65..0ac41c6 100644 --- a/src/templates.ts +++ b/src/templates.ts @@ -87,6 +87,10 @@ export class Templates { scripts.push(``) }) + scripts.push( + `` + ) + return { styles: `${styles.join('\n')}\n${injectedStyles}`, scripts: scripts.join('\n') } } @@ -199,6 +203,7 @@ export class Templates { }) const cause = await this.#tmplToHTML('errorCause', props) const metadata = await this.#tmplToHTML('errorMetadata', props) + return `${header}${info}${stackTrace}${cause}${metadata}` }, }) diff --git a/src/templates/error_stack/main.ts b/src/templates/error_stack/main.ts index a13e635..806582c 100644 --- a/src/templates/error_stack/main.ts +++ b/src/templates/error_stack/main.ts @@ -13,7 +13,7 @@ import { dump as dumpCli } from '@poppinss/dumper/console' import { publicDirURL } from '../../public_dir.js' import { BaseComponent } from '../../component.js' -import { htmlEscape, colors } from '../../helpers.js' +import { htmlEscape, colors, getAddEventListenerLine } from '../../helpers.js' import type { ErrorStackProps } from '../../types.js' const CHEVIRON = ` @@ -41,7 +41,16 @@ const EDITORS: Record = { export class ErrorStack extends BaseComponent { cssFile = new URL('./error_stack/style.css', publicDirURL) scriptFile = new URL('./error_stack/script.js', publicDirURL) - + eventHandlers = [ + getAddEventListenerLine({ + id: 'formatted-frames', + handler: `function(){showFormattedFrames(this)}`, + }), + getAddEventListenerLine({ + id: 'raw-frames', + handler: `function(){showRawFrames(this)}`, + }), + ] /** * Returns the file's relative name from the CWD */ @@ -91,7 +100,7 @@ export class ErrorStack extends BaseComponent { /** * Returns the HTML fragment for the frame location */ - #renderFrameLocation(frame: StackFrame, id: string, ide: string) { + #renderFrameLocation(frame: StackFrame, id: string, ide: string, index: number) { const { text, href } = this.#getEditorLink(ide, frame) const fileName = ` @@ -107,7 +116,16 @@ export class ErrorStack extends BaseComponent { const loc = `at line ${frame.lineNumber}:${frame.columnNumber}` if (frame.type !== 'native' && frame.source) { - return `` } @@ -126,19 +144,30 @@ export class ErrorStack extends BaseComponent { expandAtIndex: number, props: ErrorStackProps ) { - const id = `frame-${index + 1}` + const frameIndex = index + 1 + const id = `frame-${frameIndex}` const label = frame.type === 'app' ? 'In App' : '' const expandedClass = expandAtIndex === index ? 'expanded' : '' - const toggleButton = - frame.type !== 'native' && frame.source - ? `` - : '' + } return `
  • - ${this.#renderFrameLocation(frame, id, props.ide)} + ${this.#renderFrameLocation(frame, id, props.ide, frameIndex)}
    ${label} ${toggleButton} @@ -204,8 +233,8 @@ export class ErrorStack extends BaseComponent {
    - - + +
    diff --git a/src/templates/header/main.ts b/src/templates/header/main.ts index e59d050..880009d 100644 --- a/src/templates/header/main.ts +++ b/src/templates/header/main.ts @@ -8,6 +8,7 @@ */ import { BaseComponent } from '../../component.js' +import { getAddEventListenerLine } from '../../helpers.js' import { publicDirURL } from '../../public_dir.js' import type { ComponentSharedProps } from '../../types.js' @@ -23,6 +24,18 @@ export class Header extends BaseComponent { cssFile = new URL('./header/style.css', publicDirURL) scriptFile = new URL('./header/script.js', publicDirURL) + /** + * List of header event handlers to add in the generated HTML + * and respond to user actions + */ + eventHandlers = [ + getAddEventListenerLine({ + id: 'toggle-theme-checkbox', + handler: 'function(){toggleTheme(this)}', + event: 'change', + }), + ] + /** * The toHTML method is used to output the HTML for the * web view @@ -31,7 +44,7 @@ export class Header extends BaseComponent { return `