From acaf99a80cbcd54c1abf12cb62afbcdba50bbf00 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Thu, 21 Oct 2021 11:39:23 -0700 Subject: [PATCH] fix: support receiving events from class api templates --- .../basic/node.render.expected.html | 6 ++++ .../basic/web.render.expected.html | 6 ++++ .../basic/web.step-0.expected.html | 6 ++++ .../class-api-event-handlers/index.test.ts | 25 ++++++++++++++++ .../templates/basic.marko | 3 ++ .../templates/components/fancy-button.marko | 9 ++++++ .../class-api-custom-tag-handlers.ts | 29 +++++++++++++++++++ src/translate/index.ts | 9 +++++- 8 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/node.render.expected.html create mode 100644 src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.render.expected.html create mode 100644 src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.step-0.expected.html create mode 100644 src/__tests__/fixtures/misc/class-api-event-handlers/index.test.ts create mode 100644 src/__tests__/fixtures/misc/class-api-event-handlers/templates/basic.marko create mode 100644 src/__tests__/fixtures/misc/class-api-event-handlers/templates/components/fancy-button.marko create mode 100644 src/translate/class-api-custom-tag-handlers.ts diff --git a/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/node.render.expected.html b/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/node.render.expected.html new file mode 100644 index 0000000..ae6bd61 --- /dev/null +++ b/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/node.render.expected.html @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.render.expected.html b/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.render.expected.html new file mode 100644 index 0000000..ae6bd61 --- /dev/null +++ b/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.render.expected.html @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.step-0.expected.html b/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.step-0.expected.html new file mode 100644 index 0000000..ae6bd61 --- /dev/null +++ b/src/__tests__/fixtures/misc/class-api-event-handlers/__snapshots__/misc-native-tag-event-handlers/basic/web.step-0.expected.html @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/src/__tests__/fixtures/misc/class-api-event-handlers/index.test.ts b/src/__tests__/fixtures/misc/class-api-event-handlers/index.test.ts new file mode 100644 index 0000000..9e4feee --- /dev/null +++ b/src/__tests__/fixtures/misc/class-api-event-handlers/index.test.ts @@ -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(); + }, + ]) + ); +}); diff --git a/src/__tests__/fixtures/misc/class-api-event-handlers/templates/basic.marko b/src/__tests__/fixtures/misc/class-api-event-handlers/templates/basic.marko new file mode 100644 index 0000000..f6dca52 --- /dev/null +++ b/src/__tests__/fixtures/misc/class-api-event-handlers/templates/basic.marko @@ -0,0 +1,3 @@ + + onValue(1))>emit 1 + onValue(2))>emit 2 diff --git a/src/__tests__/fixtures/misc/class-api-event-handlers/templates/components/fancy-button.marko b/src/__tests__/fixtures/misc/class-api-event-handlers/templates/components/fancy-button.marko new file mode 100644 index 0000000..224d94d --- /dev/null +++ b/src/__tests__/fixtures/misc/class-api-event-handlers/templates/components/fancy-button.marko @@ -0,0 +1,9 @@ +class { + handleClick() { + this.emit("click"); + } +} + + diff --git a/src/translate/class-api-custom-tag-handlers.ts b/src/translate/class-api-custom-tag-handlers.ts new file mode 100644 index 0000000..bae59ba --- /dev/null +++ b/src/translate/class-api-custom-tag-handlers.ts @@ -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) { + 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; diff --git a/src/translate/index.ts b/src/translate/index.ts index e23c258..0b45ccd 100644 --- a/src/translate/index.ts +++ b/src/translate/index.ts @@ -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[];