chocola 1.3.11 → 1.4.2

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.
@@ -43,12 +43,12 @@ function scopeCss(cssString, cssId) {
43
43
  .filter(Boolean);
44
44
  const scopedHeader = selectors.length > 0
45
45
  ? selectors.map(sel => {
46
- const s = sel.trim();
47
- if (s.startsWith("." + cssId)) {
48
- return s;
49
- }
50
- return `.${cssId} ${s}`;
51
- }).join(", ")
46
+ const s = sel.trim();
47
+ if (s.startsWith("." + cssId)) {
48
+ return s;
49
+ }
50
+ return `.${cssId} ${s}`;
51
+ }).join(", ")
52
52
  : header;
53
53
  out += scopedHeader + "{" + innerScoped + "}";
54
54
  }
@@ -61,7 +61,6 @@ function scopeCss(cssString, cssId) {
61
61
  return processBlock(cssString);
62
62
  }
63
63
 
64
-
65
64
  function interpolateNode(node, ctxProxy) {
66
65
  if (node.nodeType === 3) {
67
66
  node.textContent = node.textContent.replace(/\{([^}]+)\}/g, (_, expr) => {
@@ -76,7 +75,6 @@ function interpolateNode(node, ctxProxy) {
76
75
  }
77
76
  }
78
77
 
79
-
80
78
  /**
81
79
  * Processes a single component element and inserts it into the DOM
82
80
  * @param {Element} element
@@ -95,11 +93,24 @@ export function processComponentElement(
95
93
  runtimeMap,
96
94
  cssScopes,
97
95
  cssScopesMap,
98
- scopedStyles
96
+ scopedStyles,
97
+ renderChain = [],
98
+ staticCtxRegistry
99
99
  ) {
100
100
  const tagName = element.tagName.toLowerCase();
101
101
  const compName = tagName + ".js";
102
- const ctx = extractContextFromElement(element);
102
+ const instance = loadedComponents.get(compName);
103
+
104
+ if (!instance || instance === undefined) return false;
105
+ if (renderChain && renderChain.includes(compName)) return false;
106
+
107
+ let ctx;
108
+ if (staticCtxRegistry && staticCtxRegistry.has(element)) {
109
+ ctx = staticCtxRegistry.get(element);
110
+ } else {
111
+ ctx = extractContextFromElement(element);
112
+ staticCtxRegistry && staticCtxRegistry.set(element, ctx);
113
+ }
103
114
  const srcInnerHtml = element.innerHTML;
104
115
 
105
116
  const ctxProxy = new Proxy(ctx, {
@@ -107,33 +118,56 @@ export function processComponentElement(
107
118
  get(target, key) { return target[key]; }
108
119
  });
109
120
 
110
- const instance = loadedComponents.get(compName);
111
- if (!instance || instance === undefined) return false;
112
-
113
121
  if (instance.body) {
114
122
  let body = instance.body;
115
123
 
116
124
  const fragment = JSDOM.fragment(body);
125
+
126
+ const slotFragment = JSDOM.fragment(srcInnerHtml);
127
+ Array.from(fragment.querySelectorAll("slot")).forEach(slot => {
128
+ slot.replaceWith(slotFragment);
129
+ });
130
+
117
131
  const children = Array.from(fragment.querySelectorAll("*"));
118
132
 
119
133
  children.forEach(child => {
120
134
  const reservedAttrs = ["if", "del-if"];
135
+
121
136
  Array.from(child.attributes).forEach(attribute => {
122
137
  if (!attribute || attribute === undefined) return;
123
138
  if (reservedAttrs.includes(attribute.name)) return;
124
139
  attribute.value = attribute.value.replace(
125
140
  /\{([^}]+)\}/g,
126
- (_, key) => ctx[key] ?? ""
141
+ (_, expr) => {
142
+ try {
143
+ return Function("ctx", `with(ctx) { return (${expr}); }`)(ctxProxy);
144
+ } catch {
145
+ return "";
146
+ }
147
+ }
127
148
  );
128
149
  });
129
150
 
151
+ processComponentElement(
152
+ child,
153
+ loadedComponents,
154
+ runtimeChunks,
155
+ compIdColl,
156
+ letterState,
157
+ runtimeMap,
158
+ cssScopes,
159
+ cssScopesMap,
160
+ scopedStyles,
161
+ renderChain.concat(compName),
162
+ staticCtxRegistry
163
+ );
164
+
130
165
  ["if", "del-if"].forEach(statement => {
131
166
  const statAtt = child.getAttribute(statement);
132
167
  if (!statAtt) return;
133
168
  const expr = statAtt.slice(1, -1);
134
- const eva = ctxProxy[expr] ? ctxProxy[expr].slice(1, -1) : null;
135
- const fn = new Function("ctx", `{ return (${eva}); }`);
136
- if (!fn()) {
169
+ const fn = new Function("ctx", `with(ctx) { return (${expr}); }`);
170
+ if (!fn(ctxProxy)) {
137
171
  if (statement === "if") child.style.display = "none";
138
172
  if (statement === "del-if") child.remove();
139
173
  }
@@ -184,11 +218,6 @@ export function processComponentElement(
184
218
  }
185
219
  }
186
220
 
187
- const slotFragment = JSDOM.fragment(srcInnerHtml);
188
- Array.from(fragment.querySelectorAll("slot")).forEach(slot => {
189
- slot.replaceWith(slotFragment);
190
- });
191
-
192
221
  let style = instance.styles && instance.styles.toString();
193
222
  if (style) {
194
223
  let cssId = cssScopesMap && cssScopesMap.get(compName);
@@ -228,9 +257,10 @@ export function processAllComponents(appElements, loadedComponents) {
228
257
  let cssScopes = [];
229
258
  let cssScopesMap = new Map();
230
259
  let scopedStyles = [];
260
+ let staticCtxRegistry = new Map();
231
261
 
232
262
  appElements.forEach(el => {
233
- processComponentElement(el, loadedComponents, runtimeChunks, compIdColl, letterState, runtimeMap, cssScopes, cssScopesMap, scopedStyles);
263
+ processComponentElement(el, loadedComponents, runtimeChunks, compIdColl, letterState, runtimeMap, cssScopes, cssScopesMap, scopedStyles, [], staticCtxRegistry);
234
264
  });
235
265
  const runtimeScript = runtimeChunks.join("\n");
236
266
  const hasComponents = runtimeChunks.length > 0;
@@ -103,6 +103,7 @@ export async function getSrcIndex(srcPath) {
103
103
  export async function processStylesheet(link, rootDir, srcDir, outDirPath, fileIds) {
104
104
  try {
105
105
  const href = link.href;
106
+ if (href.startsWith("http://") || href.startsWith("https://")) return;
106
107
  const stylesheetPath = path.join(rootDir, srcDir, href);
107
108
  const css = await fs.readFile(stylesheetPath, { encoding: "utf8" });
108
109
  const cssFileName = "css-" + genRandomId(fileIds, 6) + ".css";
@@ -233,6 +234,7 @@ export async function copyResources(rootDir, scopesCss, globalCss, srcDir, outDi
233
234
  const cssAssets = [...getCssAssets(scopesCss), ...getCssAssets(globalCss)];
234
235
  for (const assetPath of cssAssets) {
235
236
  try {
237
+ if (assetPath.startsWith('http:') || assetPath.startsWith('https:')) continue;
236
238
  const srcPath = path.join(rootDir, srcDir, assetPath);
237
239
  const destPath = path.join(outDirPath, assetPath);
238
240
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chocola",
3
- "version": "1.3.11",
3
+ "version": "1.4.2",
4
4
  "description": "The sweetest way to build reactive web apps",
5
5
  "keywords": [
6
6
  "web",