mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
feat: event handler implicit components
This commit is contained in:
parent
c8970e0719
commit
2d0a566a56
7
.changeset/shaggy-teachers-pay.md
Normal file
7
.changeset/shaggy-teachers-pay.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@marko/translator-default": minor
|
||||
"@marko/compiler": minor
|
||||
"marko": minor
|
||||
---
|
||||
|
||||
Using event handlers now causes a template to become an implicit component or split component (depending on if a string event handler is used).
|
||||
1
packages/marko/src/runtime/helpers/empty-component.js
Normal file
1
packages/marko/src/runtime/helpers/empty-component.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = {};
|
||||
@ -0,0 +1,4 @@
|
||||
<button id=input.id onClick(() => {
|
||||
component.emit("click");
|
||||
})>Click me</button>
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
$ if (typeof window === "object") throw new Error("Should be server only");
|
||||
<button id=input.id onClick("emit", "click")>Click me</button>
|
||||
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
onMount() {
|
||||
window.testComponent = this;
|
||||
this.clicks = 0;
|
||||
},
|
||||
trackClick() {
|
||||
this.clicks++;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
html lang="en"
|
||||
head
|
||||
meta charset="UTF-8"
|
||||
title -- Marko Components Tests
|
||||
body
|
||||
|
||||
div id="test"
|
||||
div id="mocha"
|
||||
div id="testsTarget"
|
||||
|
||||
app-button-split id="a" onClick("trackClick")
|
||||
app-button-component id="b" onClick("trackClick")
|
||||
@ -0,0 +1,9 @@
|
||||
var expect = require("chai").expect;
|
||||
|
||||
it("should have initialized both components", function () {
|
||||
var component = window.testComponent;
|
||||
expect(component.clicks).to.equal(0);
|
||||
document.getElementById("a").click();
|
||||
expect(component.clicks).to.equal(1);
|
||||
document.getElementById("b").click();
|
||||
});
|
||||
@ -49,8 +49,8 @@ export const analyze = {
|
||||
exit(program) {
|
||||
const { file } = program.hub;
|
||||
const meta = file.metadata.marko;
|
||||
const { styleFile, packageFile, componentBrowserFile } =
|
||||
getComponentFiles(program);
|
||||
const componentFiles = getComponentFiles(program);
|
||||
const { styleFile, packageFile, componentBrowserFile } = componentFiles;
|
||||
|
||||
if (packageFile) {
|
||||
meta.deps.unshift(`package: ${packageFile}`);
|
||||
@ -62,8 +62,16 @@ export const analyze = {
|
||||
|
||||
if (meta.hasComponentBrowser) {
|
||||
meta.component = componentBrowserFile;
|
||||
} else if (meta.hasComponent || meta.hasStatefulTagParams) {
|
||||
} else if (
|
||||
meta.hasComponent ||
|
||||
meta.hasStatefulTagParams ||
|
||||
meta.hasFunctionEventHandlers
|
||||
) {
|
||||
meta.component = file.opts.filename;
|
||||
} else if (meta.hasStringEventHandlers) {
|
||||
meta.component = componentFiles.componentBrowserFile =
|
||||
"marko/src/runtime/helpers/empty-component.js";
|
||||
meta.hasComponentBrowser = true;
|
||||
}
|
||||
|
||||
meta.component =
|
||||
@ -114,6 +122,26 @@ export const analyze = {
|
||||
}
|
||||
}
|
||||
|
||||
if (!meta.hasFunctionEventHandlers || !meta.hasStringEventHandlers) {
|
||||
for (const attr of tag.node.attributes) {
|
||||
if (
|
||||
t.isMarkoAttribute(attr) &&
|
||||
attr.arguments &&
|
||||
/^on[-A-Z]/.test(attr.name)
|
||||
) {
|
||||
if (
|
||||
attr.arguments.length >= 1 &&
|
||||
attr.arguments[0].type === "StringLiteral"
|
||||
) {
|
||||
meta.hasStringEventHandlers = true;
|
||||
} else {
|
||||
meta.hasFunctionEventHandlers = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
meta.hasStatefulTagParams ||
|
||||
isNativeTag(tag) ||
|
||||
@ -138,6 +166,7 @@ export const analyze = {
|
||||
meta.hasStatefulTagParams =
|
||||
childMeta &&
|
||||
(childMeta.hasStatefulTagParams ||
|
||||
childMeta.hasFunctionEventHandlers ||
|
||||
(childMeta.hasComponent && !childMeta.hasComponentBrowser));
|
||||
},
|
||||
ImportDeclaration: {
|
||||
|
||||
@ -92,6 +92,7 @@ export default function (path, isNullable) {
|
||||
if (isHTML) {
|
||||
if (
|
||||
(!meta.hasStatefulTagParams &&
|
||||
!meta.hasFunctionEventHandlers &&
|
||||
(meta.hasComponentBrowser || !meta.hasComponent)) ||
|
||||
isPreserved(path)
|
||||
) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import path from "path";
|
||||
import { escapeRegExp } from "./escape-regexp";
|
||||
|
||||
const COMPONENT_FILES_KEY = Symbol();
|
||||
const COMPONENT_FILES_KEY = "___marko_component_files___";
|
||||
|
||||
export default function getComponentFiles({ hub: { file } }) {
|
||||
const meta = file.metadata.marko;
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
import { register, init } from "marko/src/runtime/components/index.js";
|
||||
import component_0 from "marko/src/runtime/helpers/empty-component.js";
|
||||
register("packages/translator-default/test/fixtures/error-duplicate-event-handlers/template.marko", component_0);
|
||||
init();
|
||||
@ -0,0 +1,3 @@
|
||||
import { init } from "marko/src/runtime/components/index.js";
|
||||
import "./template.marko";
|
||||
init();
|
||||
@ -0,0 +1,4 @@
|
||||
import { register, init } from "marko/src/runtime/components/index.js";
|
||||
import component_0 from "marko/src/runtime/helpers/empty-component.js";
|
||||
register("packages/translator-default/test/fixtures/error-event-handler-value/template.marko", component_0);
|
||||
init();
|
||||
@ -27,6 +27,6 @@ _marko_template._ = (0, _renderer.default)(function (input, out, _componentDef,
|
||||
(0, _renderTag.default)(_customTag2.default, {}, out, _componentDef, "5", [["camelcasedEvent", "handle", false]]);
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
s: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
@ -22,6 +22,6 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
|
||||
_marko_tag(_customTag, {}, out, _componentDef, "5", [["camelcasedEvent", "handle", false]]);
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
s: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
@ -20,5 +20,5 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
|
||||
_marko_tag(_customTag, {}, out, _componentDef, "5", [["camelcasedEvent", "handle", false]]);
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true
|
||||
s: true
|
||||
}, _marko_component);
|
||||
@ -0,0 +1,4 @@
|
||||
import { register, init } from "marko/src/runtime/components/index.js";
|
||||
import component_0 from "marko/src/runtime/helpers/empty-component.js";
|
||||
register("packages/translator-default/test/fixtures/event-handlers/template.marko", component_0);
|
||||
init();
|
||||
@ -6,7 +6,8 @@ import _customTag from "./components/custom-tag.marko";
|
||||
import _marko_tag from "marko/src/runtime/helpers/render-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/src/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
import _marko_split_component from "marko/src/runtime/helpers/empty-component.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_split_component);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
out.e("div", null, "0", _component, 0, 0, {
|
||||
@ -25,7 +26,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
|
||||
_marko_tag(_customTag, {}, out, _componentDef, "5", [["camelcasedEvent", "handle", false]]);
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
s: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/src/runtime/components/defineComponent.js";
|
||||
|
||||
@ -6,7 +6,8 @@ import _customTag from "./components/custom-tag.marko";
|
||||
import _marko_tag from "marko/dist/runtime/helpers/render-tag.js";
|
||||
import _marko_renderer from "marko/dist/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/dist/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
import _marko_split_component from "marko/dist/runtime/helpers/empty-component.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_split_component);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
out.e("div", null, "0", _component, 0, 0, {
|
||||
@ -25,7 +26,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
|
||||
_marko_tag(_customTag, {}, out, _componentDef, "5", [["camelcasedEvent", "handle", false]]);
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true
|
||||
s: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/dist/runtime/components/defineComponent.js";
|
||||
_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._);
|
||||
Loading…
x
Reference in New Issue
Block a user