chocola 2.0.0-next.4 → 2.0.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,9 +39,7 @@ export function extractContextFromElement(element) {
39
39
  }
40
40
 
41
41
  export async function serializeDOM(dom) {
42
- const beautify = (await import("js-beautify")).default;
43
- const finalHtml = restoreCurlyBraces(dom.serialize());
44
- return beautify.html(finalHtml, { indent_size: 2 });
42
+ return restoreCurlyBraces(dom.serialize());
45
43
  }
46
44
 
47
45
  export async function writeHTMLOutput(html, outDirPath) {
@@ -66,6 +64,10 @@ export function appendStylesheetLink(doc, filename) {
66
64
  doc.head.appendChild(linkEl);
67
65
  }
68
66
 
67
+ export function getScriptElements(doc) {
68
+ return Array.from(doc.querySelectorAll("script[src]"));
69
+ }
70
+
69
71
  export function appendRuntimeScript(doc, filename) {
70
72
  const runtimeScriptEl = doc.createElement("script");
71
73
  runtimeScriptEl.type = "module";
package/compiler/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { promises as fs } from "fs";
2
- import chalk from "chalk";
2
+ import chalk from "./chalk.js";
3
3
  import { loadConfig, resolvePaths } from "./config.js";
4
4
  import {
5
5
  createDOM,
6
6
  validateAppContainer,
7
7
  getAppElements,
8
8
  getAssetLinks,
9
+ getScriptElements,
9
10
  appendRuntimeScript,
10
11
  appendStylesheetLink,
11
12
  serializeDOM,
@@ -14,12 +15,13 @@ import {
14
15
  } from "./dom-processor.js";
15
16
  import { processAllComponents } from "./component-processor.js";
16
17
  import { generateRuntimeScript } from "./runtime-generator.js";
17
- import { genRandomId, throwError, compileExpression } from "./utils.js";
18
+ import { genRandomId, throwError, compileExpression, hasDelIfAttr, getDelIfAttr, removeDelIfAttr } from "./utils.js";
18
19
  import {
19
20
  copyStaticDir,
20
21
  getComponents,
21
22
  getSrcIndex,
22
23
  processIcons,
24
+ processScript,
23
25
  processStylesheet,
24
26
  } from "./pipeline.js";
25
27
 
@@ -91,6 +93,7 @@ async function loadAndDisplayComponents(srcComponentsPath) {
91
93
 
92
94
  async function processAssets(doc, rootDir, srcDir, outDirPath) {
93
95
  const { stylesheets, icons } = getAssetLinks(doc);
96
+ const scripts = getScriptElements(doc);
94
97
  const fileIds = [];
95
98
  let cssContents = [];
96
99
 
@@ -102,9 +105,81 @@ async function processAssets(doc, rootDir, srcDir, outDirPath) {
102
105
  for (const link of icons) {
103
106
  await processIcons(link, rootDir, srcDir, outDirPath);
104
107
  }
108
+
109
+ for (const script of scripts) {
110
+ await processScript(doc, script, rootDir, srcDir, outDirPath, fileIds);
111
+ }
105
112
  return cssContents
106
113
  }
107
114
 
115
+ function processPageConditionals(parent) {
116
+ const children = [...parent.children];
117
+ let chainActive = false;
118
+ let chainRendered = false;
119
+
120
+ for (const child of children) {
121
+ const hasIf = child.hasAttribute("if");
122
+ const hasDelIf = hasDelIfAttr(child);
123
+ const hasElif = child.hasAttribute("elif");
124
+ const hasElse = child.hasAttribute("else");
125
+
126
+ if (hasElif || hasElse) {
127
+ if (!chainActive) continue;
128
+ if (chainRendered) { child.remove(); continue; }
129
+ }
130
+
131
+ if (hasIf) {
132
+ const raw = child.getAttribute("if");
133
+ const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
134
+ const fn = compileExpression(expr, false);
135
+ const result = fn();
136
+ chainActive = true;
137
+ if (result) {
138
+ chainRendered = true;
139
+ } else {
140
+ child.remove();
141
+ chainRendered = false;
142
+ }
143
+ child.removeAttribute("if");
144
+ } else if (hasDelIf) {
145
+ const raw = getDelIfAttr(child);
146
+ const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
147
+ const fn = compileExpression(expr, false);
148
+ const result = fn();
149
+ chainActive = true;
150
+ if (result) {
151
+ chainRendered = true;
152
+ } else {
153
+ child.remove();
154
+ chainRendered = false;
155
+ }
156
+ removeDelIfAttr(child);
157
+ } else if (hasElif) {
158
+ const raw = child.getAttribute("elif");
159
+ const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
160
+ const fn = compileExpression(expr, false);
161
+ const result = fn();
162
+ if (result) {
163
+ chainRendered = true;
164
+ } else {
165
+ child.remove();
166
+ }
167
+ child.removeAttribute("elif");
168
+ } else if (hasElse) {
169
+ chainRendered = true;
170
+ chainActive = false;
171
+ child.removeAttribute("else");
172
+ } else {
173
+ chainActive = false;
174
+ chainRendered = false;
175
+ }
176
+
177
+ if (child.parentNode) {
178
+ processPageConditionals(child);
179
+ }
180
+ }
181
+ }
182
+
108
183
  export default async function compile(rootDir, buildConfig) {
109
184
  const isHotReload = buildConfig?.isHotReload || null;
110
185
  !isHotReload && logBanner();
@@ -129,83 +204,6 @@ export default async function compile(rootDir, buildConfig) {
129
204
  const doc = dom.window.document;
130
205
  const appContainer = validateAppContainer(doc);
131
206
 
132
- function hasDelIfAttr(el) {
133
- return el.hasAttribute("del:if");
134
- }
135
- function getDelIfAttr(el) {
136
- return el.getAttribute("del:if");
137
- }
138
- function removeDelIfAttr(el) {
139
- el.removeAttribute("del:if");
140
- }
141
-
142
- function processPageConditionals(parent) {
143
- const children = [...parent.children];
144
- let chainActive = false;
145
- let chainRendered = false;
146
-
147
- for (const child of children) {
148
- const hasIf = child.hasAttribute("if");
149
- const hasDelIf = hasDelIfAttr(child);
150
- const hasElif = child.hasAttribute("elif");
151
- const hasElse = child.hasAttribute("else");
152
-
153
- if (hasElif || hasElse) {
154
- if (!chainActive) continue;
155
- if (chainRendered) { child.remove(); continue; }
156
- }
157
-
158
- if (hasIf) {
159
- const raw = child.getAttribute("if");
160
- const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
161
- const fn = compileExpression(expr, false);
162
- const result = fn();
163
- chainActive = true;
164
- if (result) {
165
- chainRendered = true;
166
- } else {
167
- child.remove();
168
- chainRendered = false;
169
- }
170
- child.removeAttribute("if");
171
- } else if (hasDelIf) {
172
- const raw = getDelIfAttr(child);
173
- const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
174
- const fn = compileExpression(expr, false);
175
- const result = fn();
176
- chainActive = true;
177
- if (result) {
178
- chainRendered = true;
179
- } else {
180
- child.remove();
181
- chainRendered = false;
182
- }
183
- removeDelIfAttr(child);
184
- } else if (hasElif) {
185
- const raw = child.getAttribute("elif");
186
- const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
187
- const fn = compileExpression(expr, false);
188
- const result = fn();
189
- if (result) {
190
- chainRendered = true;
191
- } else {
192
- child.remove();
193
- }
194
- child.removeAttribute("elif");
195
- } else if (hasElse) {
196
- chainRendered = true;
197
- chainActive = false;
198
- child.removeAttribute("else");
199
- } else {
200
- chainActive = false;
201
- chainRendered = false;
202
- }
203
-
204
- if (child.parentNode) {
205
- processPageConditionals(child);
206
- }
207
- }
208
- }
209
207
  processPageConditionals(appContainer);
210
208
 
211
209
  const appElements = getAppElements(appContainer);
@@ -15,22 +15,23 @@ export async function getComponents(libDir) {
15
15
  throw Error(`The specified components folder ${libDir} could not be found.`);
16
16
  }
17
17
 
18
- for (const comp of components) {
19
- if (!comp.endsWith(".html")) continue;
18
+ const reads = components
19
+ .filter(comp => comp.endsWith(".html"))
20
+ .map(async (comp) => {
21
+ try {
22
+ const compPath = path.join(libDir, comp);
23
+ const instance = await fs.readFile(compPath, "utf-8");
20
24
 
21
- componentsLib.push(comp);
25
+ if (instance === "" || instance.trim().length === 0) emptyComps.push(comp);
22
26
 
23
- try {
24
- const compPath = path.join(libDir, comp);
25
- const instance = await fs.readFile(compPath, "utf-8");
27
+ loadedComponents.set(comp.toLowerCase(), instance);
28
+ componentsLib.push(comp);
29
+ } catch (err) {
30
+ throwError(`Failed to load component "${comp}": ${err.message || err}`);
31
+ }
32
+ });
26
33
 
27
- if (instance === "" || instance.trim().length === 0) emptyComps.push(comp);
28
-
29
- loadedComponents.set(comp.toLowerCase(), instance);
30
- } catch (err) {
31
- throwError(`Failed to load component "${comp}": ${err.message || err}`);
32
- }
33
- }
34
+ await Promise.all(reads);
34
35
 
35
36
  return { componentsLib, loadedComponents, emptyComps };
36
37
  } catch (err) {
@@ -83,6 +84,32 @@ export async function processIcons(link, rootDir, srcDir, outDirPath) {
83
84
  }
84
85
  }
85
86
 
87
+ export async function processScript(doc, script, rootDir, srcDir, outDirPath, fileIds) {
88
+ try {
89
+ const src = script.getAttribute("src");
90
+ if (src.startsWith("http://") || src.startsWith("https://")) return;
91
+ const scriptPath = path.join(rootDir, srcDir, src);
92
+ const content = await fs.readFile(scriptPath, { encoding: "utf8" });
93
+ const jsFileName = "js-" + genRandomId(fileIds, 6) + ".js";
94
+ await fs.writeFile(path.join(outDirPath, jsFileName), content);
95
+
96
+ const newScript = doc.createElement("script");
97
+ for (const attr of script.attributes) {
98
+ if (attr.name === "src") {
99
+ newScript.setAttribute("src", "./" + jsFileName);
100
+ } else {
101
+ newScript.setAttribute(attr.name, attr.value);
102
+ }
103
+ }
104
+ if (script.textContent.trim()) {
105
+ newScript.textContent = script.textContent;
106
+ }
107
+ script.parentNode.replaceChild(newScript, script);
108
+ } catch (err) {
109
+ throwError(`Failed to process script: ${err}`);
110
+ }
111
+ }
112
+
86
113
  export async function copyStaticDir(srcPath, outDirPath) {
87
114
  const staticSrc = path.join(srcPath, "static");
88
115
  const staticDest = path.join(outDirPath, "static");
package/compiler/utils.js CHANGED
@@ -1,13 +1,20 @@
1
- import fs from "fs/promises";
2
- import path from "path";
3
- import { pathToFileURL } from "url";
4
- import chalk from "chalk";
1
+ import chalk from "./chalk.js";
5
2
 
6
3
  export function throwError(err) {
7
4
  console.log(chalk.red.bold("Error!"), "A fatal error has occurred:\n");
8
5
  throw new Error(err);
9
6
  }
10
7
 
8
+ export function hasDelIfAttr(el) {
9
+ return el.hasAttribute("del:if");
10
+ }
11
+ export function getDelIfAttr(el) {
12
+ return el.getAttribute("del:if");
13
+ }
14
+ export function removeDelIfAttr(el) {
15
+ el.removeAttribute("del:if");
16
+ }
17
+
11
18
  export function genRandomId(collection = null, length = 10, lettersOnly = false) {
12
19
  let id;
13
20
  if (lettersOnly) {
@@ -42,15 +49,6 @@ export function incrementAlfabet(letters) {
42
49
  return "a" + arr.join("");
43
50
  }
44
51
 
45
- export function isWebLink(str) {
46
- try {
47
- const url = new URL(str);
48
- return url.protocol === "http:" || url.protocol === "https:";
49
- } catch (e) {
50
- return false;
51
- }
52
- }
53
-
54
52
  const LBRACE_PH = "_%%CHOCOLA-LBRACE%%_";
55
53
  const RBRACE_PH = "_%%CHOCOLA-RBRACE%%_";
56
54
 
package/dev/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import http from "http";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
- import chalk from "chalk";
4
+ import chalk from "../compiler/chalk.js";
5
5
  import compile from "../compiler/index.js";
6
6
  import { loadConfig, resolvePaths } from "../compiler/config.js";
7
7
  import { getChocolaConfig } from "../utils.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chocola",
3
- "version": "2.0.0-next.4",
3
+ "version": "2.0.0-next.5",
4
4
  "description": "The sweetest way to build the web",
5
5
  "keywords": [
6
6
  "web",
@@ -13,11 +13,11 @@
13
13
  ],
14
14
  "homepage": "https://chocolaframework.web.app/",
15
15
  "bugs": {
16
- "url": "https://github.com/sad-gabi/chocola/issues"
16
+ "url": "https://github.com/chocolajs/chocola/issues"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "git+https://github.com/sad-gabi/chocola.git"
20
+ "url": "git+https://github.com/chocolajs/chocola.git"
21
21
  },
22
22
  "license": "MIT",
23
23
  "author": "SadGabi",
@@ -25,7 +25,7 @@
25
25
  "main": "index.js",
26
26
  "funding": {
27
27
  "type": "github",
28
- "url": "https://github.com/sponsors/sad-gabi"
28
+ "url": "https://github.com/sponsors/chocolajs"
29
29
  },
30
30
  "scripts": {
31
31
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -35,11 +35,6 @@
35
35
  "./dev": "./dev/index.js"
36
36
  },
37
37
  "dependencies": {
38
- "chalk": "^5.6.2",
39
- "js-beautify": "^1.15.4",
40
38
  "jsdom": "^27.4.0"
41
- },
42
- "devDependencies": {
43
- "js-beautify": "^1.15.4"
44
39
  }
45
40
  }