mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
fix: avoid using mangled internal props in interop runtime
This commit is contained in:
parent
1ff2b0af54
commit
cbb9f95cb0
6
.changeset/thick-dolphins-destroy.md
Normal file
6
.changeset/thick-dolphins-destroy.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"@marko/runtime-tags": patch
|
||||
"marko": patch
|
||||
---
|
||||
|
||||
Avoid using internal mangled props from tags api in the interop runtime.
|
||||
50
.sizes.json
50
.sizes.json
@ -7,81 +7,81 @@
|
||||
{
|
||||
"name": "*",
|
||||
"total": {
|
||||
"min": 12664,
|
||||
"gzip": 5402,
|
||||
"brotli": 4922
|
||||
"min": 13282,
|
||||
"gzip": 5676,
|
||||
"brotli": 5196
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "counter",
|
||||
"user": {
|
||||
"min": 351,
|
||||
"gzip": 275,
|
||||
"brotli": 238
|
||||
"gzip": 276,
|
||||
"brotli": 241
|
||||
},
|
||||
"runtime": {
|
||||
"min": 3821,
|
||||
"gzip": 1808,
|
||||
"gzip": 1809,
|
||||
"brotli": 1614
|
||||
},
|
||||
"total": {
|
||||
"min": 4172,
|
||||
"gzip": 2083,
|
||||
"brotli": 1852
|
||||
"gzip": 2085,
|
||||
"brotli": 1855
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "counter 💧",
|
||||
"user": {
|
||||
"min": 204,
|
||||
"gzip": 180,
|
||||
"brotli": 157
|
||||
"gzip": 181,
|
||||
"brotli": 152
|
||||
},
|
||||
"runtime": {
|
||||
"min": 2683,
|
||||
"gzip": 1362,
|
||||
"brotli": 1222
|
||||
"gzip": 1361,
|
||||
"brotli": 1220
|
||||
},
|
||||
"total": {
|
||||
"min": 2887,
|
||||
"gzip": 1542,
|
||||
"brotli": 1379
|
||||
"brotli": 1372
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "comments",
|
||||
"user": {
|
||||
"min": 1182,
|
||||
"gzip": 696,
|
||||
"brotli": 637
|
||||
"gzip": 698,
|
||||
"brotli": 639
|
||||
},
|
||||
"runtime": {
|
||||
"min": 7363,
|
||||
"gzip": 3396,
|
||||
"brotli": 3091
|
||||
"min": 7358,
|
||||
"gzip": 3394,
|
||||
"brotli": 3096
|
||||
},
|
||||
"total": {
|
||||
"min": 8545,
|
||||
"min": 8540,
|
||||
"gzip": 4092,
|
||||
"brotli": 3728
|
||||
"brotli": 3735
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "comments 💧",
|
||||
"user": {
|
||||
"min": 949,
|
||||
"gzip": 583,
|
||||
"brotli": 544
|
||||
"gzip": 585,
|
||||
"brotli": 540
|
||||
},
|
||||
"runtime": {
|
||||
"min": 7887,
|
||||
"gzip": 3605,
|
||||
"brotli": 3284
|
||||
"brotli": 3283
|
||||
},
|
||||
"total": {
|
||||
"min": 8836,
|
||||
"gzip": 4188,
|
||||
"brotli": 3828
|
||||
"gzip": 4190,
|
||||
"brotli": 3823
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -1 +1 @@
|
||||
require("./runtime-dom.js").p(require("@marko/runtime-tags/debug/dom"));
|
||||
require("./runtime-dom.js").p(require("@marko/runtime-tags/debug/dom").compat);
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
import api from "@marko/runtime-tags/debug/dom";
|
||||
import { compat } from "@marko/runtime-tags/debug/dom";
|
||||
import { p } from "./runtime-dom.js";
|
||||
p(api);
|
||||
p(compat);
|
||||
|
||||
@ -1 +1 @@
|
||||
require("./runtime-dom.js").p(require("@marko/runtime-tags/dom"));
|
||||
require("./runtime-dom.js").p(require("@marko/runtime-tags/dom").compat);
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
import api from "@marko/runtime-tags/dom";
|
||||
import { compat } from "@marko/runtime-tags/dom";
|
||||
import { p } from "./runtime-dom.js";
|
||||
p(api);
|
||||
p(compat);
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
import api from "@marko/runtime-tags/debug/html";
|
||||
import * as api from "@marko/runtime-tags/debug/html";
|
||||
import { p } from "./runtime-html.js";
|
||||
export const s = p(api);
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
import api from "@marko/runtime-tags/html";
|
||||
import * as api from "@marko/runtime-tags/html";
|
||||
import { p } from "./runtime-html.js";
|
||||
export const s = p(api);
|
||||
|
||||
@ -10,71 +10,40 @@ const morphdom = require("../../vdom/morphdom");
|
||||
const { ___createFragmentNode } = require("../../vdom/morphdom/fragment");
|
||||
const dynamicTag = require("../dynamic-tag");
|
||||
|
||||
exports.p = function ({
|
||||
prepare,
|
||||
runEffects,
|
||||
patchConditionals,
|
||||
createScopeWithRenderer,
|
||||
queueEffect,
|
||||
scopeLookup,
|
||||
getRegisteredWithScope,
|
||||
register,
|
||||
}) {
|
||||
exports.p = function (domCompat) {
|
||||
dynamicTag.___runtimeCompat = function tagsToVdom(
|
||||
tagsRenderer,
|
||||
renderer,
|
||||
renderBody,
|
||||
args,
|
||||
) {
|
||||
if (
|
||||
tagsRenderer
|
||||
? tagsRenderer.___clone === undefined
|
||||
: !Array.isArray(renderBody) && renderBody?.___clone === undefined
|
||||
)
|
||||
return tagsRenderer;
|
||||
const tagsRenderer = domCompat.resolveRenderer(renderer || renderBody);
|
||||
|
||||
return (input, out) =>
|
||||
TagsCompat(
|
||||
{ i: args ? args : input, r: tagsRenderer || renderBody },
|
||||
out,
|
||||
);
|
||||
if (tagsRenderer) {
|
||||
return (input, out) =>
|
||||
TagsCompat({ i: args ? args : input, r: tagsRenderer }, out);
|
||||
}
|
||||
|
||||
return renderer;
|
||||
};
|
||||
|
||||
const TagsCompatId = "tags-compat";
|
||||
const TagsCompat = createRenderer(
|
||||
function (_, out, componentDef, component) {
|
||||
let existing = false;
|
||||
const isHydrate =
|
||||
___getComponentsContext(out).___globalContext.___isHydrate;
|
||||
const input = Array.isArray(_.i) ? _.i : [_.i];
|
||||
const tagsRenderer = resolveRegistered(_.r);
|
||||
const args = tagsRenderer.___args;
|
||||
const tagsRenderer = domCompat.resolveRenderer(_.r);
|
||||
const newNode = domCompat.render(
|
||||
isHydrate,
|
||||
out,
|
||||
component,
|
||||
tagsRenderer,
|
||||
input,
|
||||
);
|
||||
|
||||
component.effects = prepare(() => {
|
||||
if (isHydrate) {
|
||||
const scopeId = out.global.componentIdToScopeId[component.id];
|
||||
component.scope = scopeLookup[scopeId];
|
||||
}
|
||||
if (!component.scope) {
|
||||
component.scope = createScopeWithRenderer(
|
||||
tagsRenderer /* out.global as context */,
|
||||
);
|
||||
for (const signal of tagsRenderer.___closureSignals) {
|
||||
signal(component.scope, true);
|
||||
}
|
||||
} else {
|
||||
args && args(component.scope, input, 1);
|
||||
existing = true;
|
||||
}
|
||||
args && args(component.scope, input);
|
||||
});
|
||||
out.bf(out.___assignedKey, component, existing);
|
||||
if (!existing) {
|
||||
out.node({
|
||||
___actualize: () =>
|
||||
component.scope.___startNode === component.scope.___endNode
|
||||
? component.scope.___startNode
|
||||
: component.scope.___startNode.parentNode,
|
||||
});
|
||||
out.bf(out.___assignedKey, component, !newNode);
|
||||
if (newNode) {
|
||||
out.node({ ___actualize: () => newNode });
|
||||
}
|
||||
out.ef();
|
||||
},
|
||||
@ -94,12 +63,8 @@ exports.p = function ({
|
||||
_: TagsCompat,
|
||||
Component: defineComponent(
|
||||
{
|
||||
onMount() {
|
||||
runEffects(this.effects);
|
||||
},
|
||||
onUpdate() {
|
||||
runEffects(this.effects);
|
||||
},
|
||||
onMount: domCompat.runComponentEffects,
|
||||
onUpdate: domCompat.runComponentEffects,
|
||||
},
|
||||
TagsCompat,
|
||||
),
|
||||
@ -114,7 +79,7 @@ exports.p = function ({
|
||||
|
||||
const rendererCache = new WeakMap();
|
||||
|
||||
patchConditionals((conditional) => (...args) => {
|
||||
domCompat.patchConditionals((conditional) => (...args) => {
|
||||
const signal = conditional(...args);
|
||||
const hasAttrs = args.length > 1;
|
||||
return (scope, renderer, clean) => {
|
||||
@ -124,17 +89,14 @@ exports.p = function ({
|
||||
|
||||
function create5to6Renderer(renderer, hasAttrs) {
|
||||
let newRenderer = renderer;
|
||||
if (renderer) {
|
||||
if (renderer && typeof renderer !== "string") {
|
||||
const rendererFromAnywhere =
|
||||
renderer._ ||
|
||||
renderer.render ||
|
||||
(renderer.renderer && renderer.renderer.renderer) ||
|
||||
renderer.renderer;
|
||||
const isMarko6 = rendererFromAnywhere
|
||||
? rendererFromAnywhere.___clone
|
||||
: renderer.___clone;
|
||||
|
||||
if (typeof renderer !== "string" && !isMarko6) {
|
||||
if (!domCompat.isRenderer(rendererFromAnywhere || renderer)) {
|
||||
newRenderer = rendererCache.get(renderer);
|
||||
if (!newRenderer) {
|
||||
const { Component } = renderer;
|
||||
@ -145,29 +107,28 @@ exports.p = function ({
|
||||
scopeId,
|
||||
) {
|
||||
for (const customEvent of customEvents) {
|
||||
customEvent[1] = resolveRegistered(customEvent[1]);
|
||||
customEvent[1] = domCompat.resolveRenderer(customEvent[1]);
|
||||
}
|
||||
|
||||
setCustomEvents.call(this, customEvents, scopeId);
|
||||
};
|
||||
}
|
||||
newRenderer = {
|
||||
___setup(scope) {
|
||||
newRenderer = domCompat.createRenderer(
|
||||
(scope) => {
|
||||
if (!hasAttrs) {
|
||||
renderAndMorph(scope, rendererFromAnywhere, renderer, {});
|
||||
}
|
||||
},
|
||||
___clone() {
|
||||
() => {
|
||||
const realFragment = document.createDocumentFragment();
|
||||
___createFragmentNode(null, null, realFragment);
|
||||
return realFragment;
|
||||
},
|
||||
___hasUserEffects: 1,
|
||||
___args(scope, input, clean) {
|
||||
(scope, input, clean) => {
|
||||
if (clean) return;
|
||||
renderAndMorph(scope, rendererFromAnywhere, renderer, input);
|
||||
},
|
||||
};
|
||||
);
|
||||
rendererCache.set(renderer, newRenderer);
|
||||
}
|
||||
}
|
||||
@ -175,18 +136,18 @@ exports.p = function ({
|
||||
return newRenderer;
|
||||
}
|
||||
|
||||
register("@marko/tags-compat-5-to-6", create5to6Renderer);
|
||||
domCompat.register("@marko/tags-compat-5-to-6", create5to6Renderer);
|
||||
|
||||
function renderAndMorph(scope, renderer, renderBody, input) {
|
||||
const out = defaultCreateOut();
|
||||
let rootNode = scope.___startNode.fragment;
|
||||
let host = domCompat.getStartNode(scope);
|
||||
let rootNode = host.fragment;
|
||||
if (!rootNode) {
|
||||
const component = (scope.marko5Component = ___componentLookup[scope.m5c]);
|
||||
rootNode = component.___rootNode;
|
||||
scope.___startNode = rootNode.startNode;
|
||||
scope.___endNode = rootNode.endNode;
|
||||
host = rootNode.startNode;
|
||||
domCompat.setScopeNodes(host, rootNode.endNode);
|
||||
}
|
||||
const host = scope.___startNode;
|
||||
const existingComponent = scope.marko5Component;
|
||||
const componentsContext = ___getComponentsContext(out);
|
||||
const globalComponentsContext = componentsContext.___globalContext;
|
||||
@ -215,7 +176,7 @@ exports.p = function ({
|
||||
RenderBodyComponent({ renderBody, args: input }, out);
|
||||
}
|
||||
|
||||
queueEffect(scope, () => {
|
||||
domCompat.queueEffect(scope, () => {
|
||||
const targetNode = out.___getOutput().___firstChild;
|
||||
morphdom(rootNode, targetNode, host, componentsContext);
|
||||
const componentDefs = componentsContext.___initComponents(
|
||||
@ -267,12 +228,4 @@ exports.p = function ({
|
||||
_: RenderBodyComponent,
|
||||
Component: defineComponent({}, RenderBodyComponent),
|
||||
}));
|
||||
|
||||
function resolveRegistered(renderer) {
|
||||
if (!Array.isArray(renderer)) return renderer;
|
||||
|
||||
const [registerId, scopeId] = renderer;
|
||||
const scope = scopeLookup[scopeId];
|
||||
return getRegisteredWithScope(registerId, scope);
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,7 +6,6 @@ export {
|
||||
loopIn,
|
||||
loopTo,
|
||||
inLoopScope,
|
||||
patchConditionals,
|
||||
} from "./dom/control-flow";
|
||||
|
||||
export {
|
||||
@ -67,3 +66,5 @@ export {
|
||||
values,
|
||||
intersections,
|
||||
} from "./dom/signals";
|
||||
|
||||
export { compat } from "./dom/compat";
|
||||
|
||||
87
packages/runtime-tags/src/dom/compat.ts
Normal file
87
packages/runtime-tags/src/dom/compat.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import { patchConditionals } from "./control-flow";
|
||||
import { prepare, queueEffect, runEffects } from "./queue";
|
||||
import {
|
||||
createRenderer,
|
||||
createScopeWithRenderer,
|
||||
type Renderer,
|
||||
} from "./renderer";
|
||||
import { getRegisteredWithScope, register, scopeLookup } from "./resume";
|
||||
|
||||
export const compat = {
|
||||
register,
|
||||
patchConditionals,
|
||||
queueEffect,
|
||||
isRenderer(renderer: any) {
|
||||
return renderer.___clone !== undefined;
|
||||
},
|
||||
getStartNode(scope: any) {
|
||||
return scope.___startNode;
|
||||
},
|
||||
setScopeNodes(scope: any, startNode: Node, endNode: Node) {
|
||||
scope.___startNode = startNode;
|
||||
scope.___endNode = endNode;
|
||||
},
|
||||
runComponentEffects(this: any) {
|
||||
runEffects(this.effects);
|
||||
},
|
||||
resolveRenderer(renderer: any) {
|
||||
if (renderer && typeof renderer === "object") {
|
||||
if (Array.isArray(renderer)) {
|
||||
const [registerId, scopeId] = renderer;
|
||||
const scope = scopeLookup[scopeId];
|
||||
return getRegisteredWithScope(registerId, scope);
|
||||
}
|
||||
|
||||
if (renderer.___clone) {
|
||||
return renderer;
|
||||
}
|
||||
}
|
||||
},
|
||||
createRenderer(
|
||||
setup: Renderer["___setup"],
|
||||
clone: Renderer["___clone"],
|
||||
args: Renderer["___args"],
|
||||
) {
|
||||
const renderer = createRenderer("", undefined, setup, undefined, 1, args);
|
||||
renderer.___clone = clone;
|
||||
return renderer;
|
||||
},
|
||||
render(
|
||||
isHydrate: boolean,
|
||||
out: any,
|
||||
component: any,
|
||||
renderer: Renderer,
|
||||
input: any,
|
||||
) {
|
||||
const args = renderer.___args || noop;
|
||||
let existing = false;
|
||||
let scope: any = isHydrate
|
||||
? (component.scope =
|
||||
scopeLookup[(out.global.componentIdToScopeId as any)[component.id]])
|
||||
: component.scope;
|
||||
|
||||
component.effects = prepare(() => {
|
||||
if (!scope) {
|
||||
scope = component.scope = createScopeWithRenderer(renderer, out.global);
|
||||
const closures = renderer.___closureSignals;
|
||||
if (closures) {
|
||||
for (const signal of closures) {
|
||||
signal(component.scope, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args(scope, input, 1);
|
||||
existing = true;
|
||||
}
|
||||
args(scope, input);
|
||||
});
|
||||
|
||||
if (!existing) {
|
||||
return scope.___startNode === scope.___endNode
|
||||
? scope.___startNode
|
||||
: scope.___startNode.parentNode;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function noop() {}
|
||||
Loading…
x
Reference in New Issue
Block a user