From 202abdbf3e63536e21496fcd0b7ee5ec2611f229 Mon Sep 17 00:00:00 2001 From: Benjamin Atkin Date: Tue, 11 Apr 2023 00:04:11 -0700 Subject: [PATCH 1/2] add editor build --- builder.js | 120 +++++++++++++++++++++++++++++++++--------------- editor-build.js | 36 +++++++++++++++ 2 files changed, 118 insertions(+), 38 deletions(-) create mode 100644 editor-build.js diff --git a/builder.js b/builder.js index f0fc4f0..9b82d1f 100644 --- a/builder.js +++ b/builder.js @@ -1,4 +1,39 @@ -class Builder { +const defaultHtml = ` + + + + + macchiato.dev + + + + + ${ '<' + 'script type="module" src="/app.js"><' + '/script>' } + + + +`.trim() + +const defaultIntro = ` + +window.Macchiato = { + location: new MLocation(), +} + +`.trim() + +export class Builder { constructor(files) { this.files = files } @@ -39,44 +74,53 @@ class Builder { return script.outerHTML } + buildReplace(filesMap) { + if ('_replace.js' in filesMap) { + const rSrc = filesMap['_replace.js'] + return new Function( + rSrc.match(/\((\w+)\)/)[1], + rSrc.slice( + rSrc.indexOf('{') + 1, + rSrc.lastIndexOf('}') + ) + ) + } else { + return s => s + } + } + build() { - const modules = this.files.map(file => { - return this.buildModule(file) + const filesMap = Object.fromEntries( + this.files.map( + ({name, data}) => ([name, data]) + ) + ) + const intro = this.buildModule({ + name: '_intro.js', + data: ( + '_intro.js' in filesMap ? + filesMap['_intro.js'] : + defaultIntro + ), }) - return ` - - - - Editor - - - -${'<'}script type="module"> -window.Macchiato = {modules: {}} -${' -${modules.join("\n")} -${'<'}script type="module"> - -${' - - - `.trim() + const replace = this.buildReplace(filesMap) + const modules = this.files.filter(({name}) => ( + name.endsWith('.js') && + !name.startsWith('_') + )).map(file => ( + this.buildModule({ + ...file, + data: replace(file.data), + }) + )) + const html = ( + 'index.html' in filesMap ? + filesMap['index.html'] : + defaultHtml + ) + return html.replace( + '<' + 'script type="module" src="/app.js"><' + '/script>', + intro + "\n" + modules.join("\n") + ) } } \ No newline at end of file diff --git a/editor-build.js b/editor-build.js new file mode 100644 index 0000000..085003a --- /dev/null +++ b/editor-build.js @@ -0,0 +1,36 @@ +import { Builder } from '/loader/builder.js' + +export class EditorBuild { + deps = [ + '/editor/file-group.js', + '/editor/file-view.js', + '/editor/text-edit.js', + '/editor/app.js', + '/forms/button-group.js', + '/dialog/dialog.js', + '/menu/dropdown.js', + ] + + constructor() { + this.files = undefined + } + + async loadFiles() { + const files = [] + for (const name of this.deps) { + const resp = await fetch(name) + files.push({ + name, + data: await resp.text(), + }) + } + } + + async build() { + if (this.files === undefined) { + await this.loadFiles() + } + const builder = new Builder(this.files) + return builder.build() + } +} \ No newline at end of file From 5c91f5aa7ed5c7f268e64bf180b2604faa1ac23d Mon Sep 17 00:00:00 2001 From: Benjamin Atkin Date: Tue, 11 Apr 2023 12:23:28 -0700 Subject: [PATCH 2/2] build sandbox pages --- builder.js | 35 +++++++++++++++++++++++++++++++---- editor-build.js | 18 ++++++++++-------- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/builder.js b/builder.js index 9b82d1f..f46255c 100644 --- a/builder.js +++ b/builder.js @@ -28,7 +28,7 @@ html { const defaultIntro = ` window.Macchiato = { - location: new MLocation(), + modules: {}, } `.trim() @@ -38,6 +38,12 @@ export class Builder { this.files = files } + buildStyle(file) { + const style = document.createElement('style') + style.textContent = file.data + return style.outerHTML + } + buildModule(file) { const script = document.createElement('script') script.setAttribute('type', 'module') @@ -113,14 +119,35 @@ export class Builder { data: replace(file.data), }) )) - const html = ( + const styles = this.files.filter(({name}) => ( + name.endsWith('.css') + )).map(file => ( + this.buildStyle(file) + )) + let html = ( 'index.html' in filesMap ? filesMap['index.html'] : defaultHtml ) - return html.replace( + let replaced = false + html = html.replace(/\s*<\/head>/, match => { + replaced = true + return styles.join("\n") + "\n" + match + }) + if (!replaced) { + html = styles.join("\n") + "\n" + html + } + replaced = false + html = html.replace( '<' + 'script type="module" src="/app.js"><' + '/script>', - intro + "\n" + modules.join("\n") + () => { + replaced = true + return intro + "\n" + modules.join("\n") + } ) + if (!replaced) { + html += "\n" + intro + "\n" + modules.join("\n") + } + return html } } \ No newline at end of file diff --git a/editor-build.js b/editor-build.js index 085003a..f98c140 100644 --- a/editor-build.js +++ b/editor-build.js @@ -1,14 +1,15 @@ -import { Builder } from '/loader/builder.js' +import { Builder } from "/loader/builder.js" export class EditorBuild { deps = [ - '/editor/file-group.js', - '/editor/file-view.js', - '/editor/text-edit.js', - '/editor/app.js', - '/forms/button-group.js', - '/dialog/dialog.js', - '/menu/dropdown.js', + 'forms/button-group.js', + 'dialog/dialog.js', + 'menu/dropdown.js', + 'editor/file-group.js', + 'editor/file-view.js', + 'editor/text-edit.js', + 'loader/builder.js', + 'editor/app.js', ] constructor() { @@ -24,6 +25,7 @@ export class EditorBuild { data: await resp.text(), }) } + this.files = files } async build() {