Skip to content

Commit

Permalink
fix: support receiving events from class api templates
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Oct 21, 2021
1 parent 03b5a8d commit acaf99a
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<button>
emit 1
</button>
<button>
emit 2
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<button>
emit 1
</button>
<button>
emit 2
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<button>
emit 1
</button>
<button>
emit 2
</button>
25 changes: 25 additions & 0 deletions src/__tests__/fixtures/misc/class-api-event-handlers/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { spy, resetHistory } from "sinon";
import fixture from "../../../fixture";

const onValue = spy();

describe("misc native tag event handlers", () => {
describe(
"basic",
fixture("./templates/basic.marko", [
{ onValue },
async ({ expect, fireEvent, screen }) => {
expect(onValue).has.not.been.called;

await fireEvent.click(screen.getByText("emit 1"));

expect(onValue).has.been.calledOnceWith(1);
resetHistory();

await fireEvent.click(screen.getByText("emit 2"));
expect(onValue).has.been.calledOnceWith(2);
resetHistory();
},
])
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<attrs/{ onValue }/>
<fancy-button onClick=(() => onValue(1))>emit 1</fancy-button>
<fancy-button onClick=(() => onValue(2))>emit 2</fancy-button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class {
handleClick() {
this.emit("click");
}
}

<button onClick("handleClick")>
<${input.renderBody}/>
</button>
29 changes: 29 additions & 0 deletions src/translate/class-api-custom-tag-handlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { types as t } from "@marko/compiler";
import { loadFileForTag } from "@marko/babel-utils";
import isApi from "../util/is-api";
const eventNameReg = /^on[A-Z]/;

// Translates all event handlers that are on class api child tags to use the `onEvent(handler)` api.
// This allows tags api templates to consume events from class api templates.
export default {
MarkoTag(tag: t.NodePath<t.MarkoTag>) {
if (isApi(tag, "class")) return;
let childFile: t.BabelFile | undefined;

for (const attr of tag.get("attributes")) {
if (
attr.isMarkoAttribute() &&
!attr.node.arguments &&
eventNameReg.test(attr.node.name)
) {
if (
!(childFile ||= loadFileForTag(tag)) ||
isApi(childFile.path, "tags")
)
return;
attr.node.arguments = [attr.node.value];
attr.node.value = t.booleanLiteral(true);
}
}
},
} as t.Visitor;
9 changes: 8 additions & 1 deletion src/translate/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { types as t } from "@marko/compiler";
import classApiCustomTagHandlers from "./class-api-custom-tag-handlers";
import nativeTagHandlers from "./native-tag-handlers/translate";
import trackRendering from "./track-rendering/translate";
import forKeyScope from "./for-key-scope";
export = [nativeTagHandlers, trackRendering, forKeyScope] as t.Visitor[];

export = [
classApiCustomTagHandlers,
nativeTagHandlers,
trackRendering,
forKeyScope,
] as t.Visitor[];

0 comments on commit acaf99a

Please sign in to comment.