Skip to content

Commit 31732b1

Browse files
naive implementation of derived attribute tracking
1 parent 4636a3d commit 31732b1

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

src/jsx-loader.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,16 @@ function findThisReferences(context, statement) {
226226
// const { description } = this.todo;
227227
references.push(init.property.name);
228228
} else if (init.type === 'ThisExpression' && id && id.properties) {
229-
// const { description } = this.todo;
229+
// const { id, description } = this;
230230
id.properties.forEach((property) => {
231231
references.push(property.key.name);
232232
});
233+
} else {
234+
// TODO we are just blindly tracking anything here.
235+
// everything should ideally be mapped to actual this references, to create a strong chain of direct reactivity
236+
// instead of tracking any declaration as a derived tracking attr
237+
// for convenience here, we push the entire declaration here, instead of the name like for direct this references (see above)
238+
references.push(declaration);
233239
}
234240
});
235241
}
@@ -276,8 +282,6 @@ export function parseJsx(moduleURL) {
276282
applyDomDepthSubstitutions(elementTree, undefined, hasShadowRoot);
277283

278284
const finalHtml = serialize(elementTree);
279-
console.debug({ finalHtml });
280-
console.debug(`${finalHtml.replace(/\n/g, '')};`);
281285
const transformed = acorn.parse(`${elementRoot}.innerHTML = \`${finalHtml}\`;`, {
282286
ecmaVersion: 'latest',
283287
sourceType: 'module'
@@ -325,12 +329,34 @@ export function parseJsx(moduleURL) {
325329
}
326330

327331
let newModuleContents = escodegen.generate(tree);
332+
const trackingAttrs = observedAttributes.filter(attr => typeof attr === 'string');
333+
// TODO ideally derivedAttrs would explicitely reference trackingAttrs
334+
// and if there are no derivedAttrs, do not include the derivedGetters / derivedSetters code in the compiled output
335+
const derivedAttrs = observedAttributes.filter(attr => typeof attr !== 'string');
336+
const derivedGetters = derivedAttrs.map(attr => {
337+
return `
338+
get_${attr.id.name}(${trackingAttrs.join(',')}) {
339+
console.log('@@@@@@@@@@@@@@@@@@@@ updating derivative value for => ${attr.id.name}');
340+
console.log('@@@@@@@@@@@@@@@@@@@@ new derivative value is =>', ${moduleContents.slice(attr.init.start, attr.init.end)});
341+
return ${moduleContents.slice(attr.init.start, attr.init.end)}
342+
}
343+
`;
344+
}).join('\n');
345+
const derivedSetters = derivedAttrs.map(attr => {
346+
const name = attr.id.name;
347+
348+
return `
349+
const old_${name} = this.get_${name}(oldValue);
350+
const new_${name} = this.get_${name}(newValue);
351+
this.update('${name}', old_${name}, new_${name});
352+
`;
353+
}).join('\n');
328354

329355
// TODO better way to determine value type?
330356
/* eslint-disable indent */
331357
newModuleContents = `${newModuleContents.slice(0, insertPoint)}
332358
static get observedAttributes() {
333-
return [${[...observedAttributes].map(attr => `'${attr}'`).join(',')}]
359+
return [${[...trackingAttrs].map(attr => `'${attr}'`).join()}]
334360
}
335361
336362
attributeChangedCallback(name, oldValue, newValue) {
@@ -348,7 +374,7 @@ export function parseJsx(moduleURL) {
348374
}
349375
if (newValue !== oldValue) {
350376
switch(name) {
351-
${observedAttributes.map((attr) => {
377+
${trackingAttrs.map((attr) => {
352378
return `
353379
case '${attr}':
354380
this.${attr} = getValue(newValue);
@@ -381,17 +407,21 @@ export function parseJsx(moduleURL) {
381407
el.textContent = el.textContent.replace(needle, newValue);
382408
break;
383409
case 'attr':
384-
console.debug(el.hasAttribute(attr))
385410
if (el.hasAttribute(el.getAttribute(attr))) {
386411
el.setAttribute(el.getAttribute(attr), newValue);
387412
}
388413
break;
389414
}
390415
})
391416
417+
if ([${[...trackingAttrs].map(attr => `'${attr}'`).join()}].includes(name)) {
418+
${derivedSetters}
419+
}
392420
console.debug('****************************');
393421
}
394422
423+
${derivedGetters}
424+
395425
${newModuleContents.slice(insertPoint)}
396426
`;
397427
/* eslint-enable indent */

0 commit comments

Comments
 (0)