fix(csr): prevent native output recursion
This commit is contained in:
@@ -2512,6 +2512,11 @@ export const REACTIVE_RUNTIME = String.raw`
|
||||
|
||||
var stmt = attr.value;
|
||||
var listener = function (event) {
|
||||
// An unbound output falls back to a same-named CustomEvent for
|
||||
// external consumers. Do not feed that synthetic event back into
|
||||
// the component's own declarative DOM handler (for example,
|
||||
// @click="output.click()"), which would recurse indefinitely.
|
||||
if (event && event.__wrnexusComponentOutput) return;
|
||||
var locals =
|
||||
decodeLoopLocals(node);
|
||||
|
||||
@@ -4167,6 +4172,7 @@ export const REACTIVE_RUNTIME = String.raw`
|
||||
bubbles: true,
|
||||
detail: detail || {},
|
||||
});
|
||||
event.__wrnexusComponentOutput = true;
|
||||
root.dispatchEvent(event);
|
||||
// Compatibility for applications using the former prefixed contract.
|
||||
root.dispatchEvent(new EventConstructor("wrnexus:" + String(name), {
|
||||
|
||||
@@ -781,6 +781,26 @@ test("development runtime allows an output with no parent binding", () => {
|
||||
expect(warnings).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("an unbound native-named output does not re-enter its DOM handler", () => {
|
||||
const win = mount(
|
||||
`<div data-scope="" data-wrn-events="click">` +
|
||||
`<button data-on-click="output.click()">go</button>` +
|
||||
`</div>`,
|
||||
);
|
||||
const root = win.document.querySelector("[data-wrn-events]") as unknown as HTMLElement;
|
||||
let outputs = 0;
|
||||
root.addEventListener("click", (event) => {
|
||||
if ((event as Event & { __wrnexusComponentOutput?: boolean }).__wrnexusComponentOutput) {
|
||||
outputs += 1;
|
||||
}
|
||||
});
|
||||
|
||||
expect(() =>
|
||||
(win.document.querySelector("button") as unknown as HTMLElement).click(),
|
||||
).not.toThrow();
|
||||
expect(outputs).toBe(1);
|
||||
});
|
||||
|
||||
test("development runtime warns when a component binding names a missing function", () => {
|
||||
const win = new Window() as unknown as Window & Record<string, unknown>;
|
||||
win.document.body.innerHTML =
|
||||
|
||||
Reference in New Issue
Block a user