experimental propagator syntax

This commit is contained in:
Orion Reed 2024-11-26 01:49:15 -05:00
parent 79cc0fa677
commit ce2b0581ae
2 changed files with 56 additions and 8 deletions

View File

@ -38,7 +38,7 @@
source="#box1"
target="#box2"
triggers="click"
expression="$target.textContent += '!'"
expression="textContent: _ + '!'"
></event-propagator>
<fc-geometry id="box3" x="350" y="200" width="30" height="30"></fc-geometry>
@ -47,7 +47,8 @@
source="#box3"
target="#box4"
triggers="move"
expression="$target.y = $source.x"
expression="y: from.x,
rotate: from.x"
></event-propagator>
<script type="module">

View File

@ -38,7 +38,7 @@ export class EventPropagator extends FolkRope {
}
#expression = '';
#function = new Function();
#function: Function | null = null;
get expression() {
return this.#expression;
}
@ -46,12 +46,56 @@ export class EventPropagator extends FolkRope {
this.mend();
this.#expression = expression;
try {
this.#function = new Function('$source', '$target', '$event', expression);
const processedExp = expression.trim();
// Process each line, looking for the first ':' to separate key from value
const processedProps = processedExp
.split('\n')
.map((line) => {
const line_trimmed = line.trim();
if (!line_trimmed || line_trimmed === '{' || line_trimmed === '}') return '';
// Remove trailing comma if it exists
const withoutComma = line_trimmed.replace(/,\s*$/, '');
const colonIndex = withoutComma.indexOf(':');
if (colonIndex === -1) return withoutComma;
const key = withoutComma.slice(0, colonIndex).trim();
const value = withoutComma.slice(colonIndex + 1).trim();
return `${key}: (function() { const _ = to[${JSON.stringify(key)}]; return ${value}; })()`;
})
.filter((line) => line)
.join(',\n');
this.#function = new Function(
'from',
'to',
'event',
`
return {
${processedProps}
};
`
);
console.log(processedProps);
this.#function = new Function(
'from',
'to',
'event',
`
return {
${processedProps}
};
`
);
} catch (error) {
console.warn('Failed to parse expression:', error);
// Use no-op function when parsing fails
this.cut();
this.#function = () => {};
this.#function = null;
}
}
@ -133,13 +177,16 @@ export class EventPropagator extends FolkRope {
super.unobserveTarget();
}
// Do we need the event at all?
evaluateExpression = (event?: Event) => {
if (this.sourceElement === null || this.targetElement === null) return;
this.stroke = 'black';
if (!this.#function) return;
try {
this.#function(this.sourceElement, this.targetElement, event);
const assignments = this.#function(this.sourceElement, this.targetElement, event);
Object.assign(this.targetElement, assignments);
} catch (error) {
console.warn('Failed to parse expression:', error);
this.stroke = 'red';
}
};