mirror of https://github.com/vuejs/core.git
feat(vapor): merge inherited attrs with current attrs
This commit is contained in:
parent
c91586528a
commit
247617612a
|
@ -29,7 +29,7 @@
|
||||||
"dev-prepare-cjs": "node scripts/prepare-cjs.js || npm run build-all-cjs",
|
"dev-prepare-cjs": "node scripts/prepare-cjs.js || npm run build-all-cjs",
|
||||||
"dev-compiler": "run-p \"dev template-explorer\" serve open",
|
"dev-compiler": "run-p \"dev template-explorer\" serve open",
|
||||||
"dev-sfc": "run-s dev-prepare-cjs dev-sfc-run",
|
"dev-sfc": "run-s dev-prepare-cjs dev-sfc-run",
|
||||||
"dev-sfc-serve": "vite packages-private/sfc-playground --host",
|
"dev-sfc-serve": "vite packages-private/sfc-playground",
|
||||||
"dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-bundler-runtime\" \"dev vue -ipf esm-browser-runtime\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
|
"dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-bundler-runtime\" \"dev vue -ipf esm-browser-runtime\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
|
||||||
"dev-vapor": "pnpm -C playground run dev",
|
"dev-vapor": "pnpm -C playground run dev",
|
||||||
"serve": "serve",
|
"serve": "serve",
|
||||||
|
|
|
@ -140,11 +140,12 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compile > directives > v-pre > basic 1`] = `
|
exports[`compile > directives > v-pre > basic 1`] = `
|
||||||
"import { template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
|
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
|
||||||
|
|
||||||
export function render(_ctx, $props) {
|
export function render(_ctx, $props) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -176,15 +177,16 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
||||||
"import { delegate as _delegate, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
"import { delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<button></button>")
|
const t0 = _template("<button></button>")
|
||||||
_delegateEvents("click")
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_delegate(n0, "click", () => _ctx.handleClick)
|
_delegate(n0, "click", () => _ctx.handleClick)
|
||||||
|
_setInheritAttrs(["id"])
|
||||||
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
|
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
|
||||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count))
|
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -199,7 +201,8 @@ exports[`compile > expression parsing > interpolation 1`] = `
|
||||||
exports[`compile > expression parsing > v-bind 1`] = `
|
exports[`compile > expression parsing > v-bind 1`] = `
|
||||||
"((_ctx) => {
|
"((_ctx) => {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { [key.value+1]: _unref(foo)[key.value+1]() }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))
|
||||||
return n0
|
return n0
|
||||||
})()"
|
})()"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -286,22 +286,24 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > props + children 1`] = `
|
exports[`compiler: element transform > props + children 1`] = `
|
||||||
"import { template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div id=\\"foo\\"><span></span></div>")
|
const t0 = _template("<div id=\\"foo\\"><span></span></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > props merging: class 1`] = `
|
exports[`compiler: element transform > props merging: class 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }]))
|
_setInheritAttrs(["class"])
|
||||||
|
_renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -324,66 +326,72 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > props merging: style 1`] = `
|
exports[`compiler: element transform > props merging: style 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setStyle(n0, ["color: green", { color: 'red' }]))
|
_setInheritAttrs(["style"])
|
||||||
|
_renderEffect(() => _setStyle(n0, ["color: green", { color: 'red' }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > static props 1`] = `
|
exports[`compiler: element transform > static props 1`] = `
|
||||||
"import { template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div id=\\"foo\\" class=\\"bar\\"></div>")
|
const t0 = _template("<div id=\\"foo\\" class=\\"bar\\"></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > v-bind="obj" 1`] = `
|
exports[`compiler: element transform > v-bind="obj" 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, _ctx.obj))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > v-bind="obj" after static prop 1`] = `
|
exports[`compiler: element transform > v-bind="obj" after static prop 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { id: "foo" }, _ctx.obj))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > v-bind="obj" before static prop 1`] = `
|
exports[`compiler: element transform > v-bind="obj" before static prop 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, _ctx.obj, { id: "foo" }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: element transform > v-bind="obj" between static props 1`] = `
|
exports[`compiler: element transform > v-bind="obj" between static props 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { id: "foo" }, _ctx.obj, { class: "bar" }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,177 +1,193 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler v-bind > .attr modifier 1`] = `
|
exports[`compiler v-bind > .attr modifier 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id))
|
_setInheritAttrs(["foo-bar"])
|
||||||
|
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .attr modifier w/ no expression 1`] = `
|
exports[`compiler v-bind > .attr modifier w/ no expression 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar))
|
_setInheritAttrs(["foo-bar"])
|
||||||
|
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .camel modifier 1`] = `
|
exports[`compiler v-bind > .camel modifier 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id))
|
_setInheritAttrs(["fooBar"])
|
||||||
|
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = `
|
exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = `
|
||||||
"import { camelize as _camelize } from 'vue';
|
"import { camelize as _camelize } from 'vue';
|
||||||
import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { [_camelize(_ctx.foo)]: _ctx.id }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .camel modifier w/ no expression 1`] = `
|
exports[`compiler v-bind > .camel modifier w/ no expression 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar))
|
_setInheritAttrs(["fooBar"])
|
||||||
|
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .prop modifier (shortband) w/ no expression 1`] = `
|
exports[`compiler v-bind > .prop modifier (shortband) w/ no expression 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar))
|
_setInheritAttrs(["fooBar"])
|
||||||
|
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .prop modifier (shorthand) 1`] = `
|
exports[`compiler v-bind > .prop modifier (shorthand) 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
|
_setInheritAttrs(["fooBar"])
|
||||||
|
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .prop modifier 1`] = `
|
exports[`compiler v-bind > .prop modifier 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
|
_setInheritAttrs(["fooBar"])
|
||||||
|
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .prop modifier w/ dynamic arg 1`] = `
|
exports[`compiler v-bind > .prop modifier w/ dynamic arg 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { ["." + _ctx.fooBar]: _ctx.id }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .prop modifier w/ no expression 1`] = `
|
exports[`compiler v-bind > .prop modifier w/ no expression 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar))
|
_setInheritAttrs(["fooBar"])
|
||||||
|
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > basic 1`] = `
|
exports[`compiler v-bind > basic 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id))
|
_setInheritAttrs(["id"])
|
||||||
|
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > dynamic arg 1`] = `
|
exports[`compiler v-bind > dynamic arg 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > dynamic arg w/ static attribute 1`] = `
|
exports[`compiler v-bind > dynamic arg w/ static attribute 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProps(n0, { [_ctx.id]: _ctx.id, foo: "bar", checked: "" }))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > no expression (shorthand) 1`] = `
|
exports[`compiler v-bind > no expression (shorthand) 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase))
|
_setInheritAttrs(["camel-case"])
|
||||||
|
_renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > no expression 1`] = `
|
exports[`compiler v-bind > no expression 1`] = `
|
||||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id))
|
_setInheritAttrs(["id"])
|
||||||
|
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id, true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > should error if empty expression 1`] = `
|
exports[`compiler v-bind > should error if empty expression 1`] = `
|
||||||
"import { template as _template } from 'vue/vapor';
|
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div arg></div>")
|
const t0 = _template("<div arg></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -126,13 +126,14 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: vModel transform > should support input (checkbox) 1`] = `
|
exports[`compiler: vModel transform > should support input (checkbox) 1`] = `
|
||||||
"import { vModelCheckbox as _vModelCheckbox, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
|
"import { vModelCheckbox as _vModelCheckbox, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<input type=\\"checkbox\\">")
|
const t0 = _template("<input type=\\"checkbox\\">")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_withDirectives(n0, [[_vModelCheckbox, () => _ctx.model]])
|
_withDirectives(n0, [[_vModelCheckbox, () => _ctx.model]])
|
||||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -150,25 +151,27 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: vModel transform > should support input (radio) 1`] = `
|
exports[`compiler: vModel transform > should support input (radio) 1`] = `
|
||||||
"import { vModelRadio as _vModelRadio, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
|
"import { vModelRadio as _vModelRadio, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<input type=\\"radio\\">")
|
const t0 = _template("<input type=\\"radio\\">")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_withDirectives(n0, [[_vModelRadio, () => _ctx.model]])
|
_withDirectives(n0, [[_vModelRadio, () => _ctx.model]])
|
||||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: vModel transform > should support input (text) 1`] = `
|
exports[`compiler: vModel transform > should support input (text) 1`] = `
|
||||||
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
|
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<input type=\\"text\\">")
|
const t0 = _template("<input type=\\"text\\">")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_withDirectives(n0, [[_vModelText, () => _ctx.model]])
|
_withDirectives(n0, [[_vModelText, () => _ctx.model]])
|
||||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||||
|
_setInheritAttrs(false)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -243,14 +246,15 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: vModel transform > should support w/ dynamic v-bind 1`] = `
|
exports[`compiler: vModel transform > should support w/ dynamic v-bind 1`] = `
|
||||||
"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<input>")
|
const t0 = _template("<input>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_withDirectives(n0, [[_vModelDynamic, () => _ctx.model]])
|
_withDirectives(n0, [[_vModelDynamic, () => _ctx.model]])
|
||||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||||
_renderEffect(() => _setDynamicProps(n0, _ctx.obj))
|
_setInheritAttrs(true)
|
||||||
|
_renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler: v-once > as root node 1`] = `
|
exports[`compiler: v-once > as root node 1`] = `
|
||||||
"import { setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { setDynamicProp as _setDynamicProp, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_setDynamicProp(n0, "id", _ctx.foo)
|
_setDynamicProp(n0, "id", _ctx.foo, true)
|
||||||
|
_setInheritAttrs(["id"])
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -588,7 +588,7 @@ describe('compiler: element transform', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains('_setDynamicProps(n0, _ctx.obj)')
|
expect(code).contains('_setDynamicProps(n0, [_ctx.obj], true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-bind="obj" after static prop', () => {
|
test('v-bind="obj" after static prop', () => {
|
||||||
|
@ -624,7 +624,9 @@ describe('compiler: element transform', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains('_setDynamicProps(n0, { id: "foo" }, _ctx.obj)')
|
expect(code).contains(
|
||||||
|
'_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true)',
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-bind="obj" before static prop', () => {
|
test('v-bind="obj" before static prop', () => {
|
||||||
|
@ -650,7 +652,9 @@ describe('compiler: element transform', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains('_setDynamicProps(n0, _ctx.obj, { id: "foo" })')
|
expect(code).contains(
|
||||||
|
'_setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true)',
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-bind="obj" between static props', () => {
|
test('v-bind="obj" between static props', () => {
|
||||||
|
@ -678,7 +682,7 @@ describe('compiler: element transform', () => {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_setDynamicProps(n0, { id: "foo" }, _ctx.obj, { class: "bar" })',
|
'_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -723,6 +727,9 @@ describe('compiler: element transform', () => {
|
||||||
delegate: true,
|
delegate: true,
|
||||||
effect: false,
|
effect: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ describe('compiler: template ref transform', () => {
|
||||||
flags: DynamicFlag.REFERENCED,
|
flags: DynamicFlag.REFERENCED,
|
||||||
})
|
})
|
||||||
expect(ir.template).toEqual(['<div></div>'])
|
expect(ir.template).toEqual(['<div></div>'])
|
||||||
expect(ir.block.operation).lengthOf(1)
|
expect(ir.block.operation).lengthOf(2)
|
||||||
expect(ir.block.operation[0]).toMatchObject({
|
expect(ir.block.operation[1]).toMatchObject({
|
||||||
type: IRNodeTypes.SET_TEMPLATE_REF,
|
type: IRNodeTypes.SET_TEMPLATE_REF,
|
||||||
element: 0,
|
element: 0,
|
||||||
value: {
|
value: {
|
||||||
|
@ -56,6 +56,9 @@ describe('compiler: template ref transform', () => {
|
||||||
})
|
})
|
||||||
expect(ir.template).toEqual(['<div></div>'])
|
expect(ir.template).toEqual(['<div></div>'])
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.DECLARE_OLD_REF,
|
type: IRNodeTypes.DECLARE_OLD_REF,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
|
|
@ -74,7 +74,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id)')
|
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('no expression', () => {
|
test('no expression', () => {
|
||||||
|
@ -104,7 +104,7 @@ describe('compiler v-bind', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id)')
|
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('no expression (shorthand)', () => {
|
test('no expression (shorthand)', () => {
|
||||||
|
@ -126,7 +126,9 @@ describe('compiler v-bind', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('_setDynamicProp(n0, "camel-case", _ctx.camelCase)')
|
expect(code).contains(
|
||||||
|
'_setDynamicProp(n0, "camel-case", _ctx.camelCase, true)',
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('dynamic arg', () => {
|
test('dynamic arg', () => {
|
||||||
|
@ -171,7 +173,7 @@ describe('compiler v-bind', () => {
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_setDynamicProps(n0, { [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title })',
|
'_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -224,7 +226,7 @@ describe('compiler v-bind', () => {
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_setDynamicProps(n0, { [_ctx.id]: _ctx.id, foo: "bar", checked: "" })',
|
'_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -286,7 +288,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id)')
|
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.camel modifier w/ no expression', () => {
|
test('.camel modifier w/ no expression', () => {
|
||||||
|
@ -310,7 +312,7 @@ describe('compiler v-bind', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar)')
|
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.camel modifier w/ dynamic arg', () => {
|
test('.camel modifier w/ dynamic arg', () => {
|
||||||
|
@ -341,7 +343,7 @@ describe('compiler v-bind', () => {
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
`_setDynamicProps(n0, { [_camelize(_ctx.foo)]: _ctx.id })`,
|
`_setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -368,7 +370,7 @@ describe('compiler v-bind', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
|
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.prop modifier w/ no expression', () => {
|
test('.prop modifier w/ no expression', () => {
|
||||||
|
@ -392,7 +394,7 @@ describe('compiler v-bind', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
|
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.prop modifier w/ dynamic arg', () => {
|
test('.prop modifier w/ dynamic arg', () => {
|
||||||
|
@ -422,7 +424,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
`_setDynamicProps(n0, { ["." + _ctx.fooBar]: _ctx.id })`,
|
`_setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true)`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -449,7 +451,7 @@ describe('compiler v-bind', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
|
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.prop modifier (shortband) w/ no expression', () => {
|
test('.prop modifier (shortband) w/ no expression', () => {
|
||||||
|
@ -473,7 +475,7 @@ describe('compiler v-bind', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
|
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.attr modifier', () => {
|
test('.attr modifier', () => {
|
||||||
|
@ -497,7 +499,7 @@ describe('compiler v-bind', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id)')
|
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id, true)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.attr modifier w/ no expression', () => {
|
test('.attr modifier w/ no expression', () => {
|
||||||
|
@ -522,6 +524,6 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar)')
|
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar, true)')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -28,7 +28,11 @@ describe('v-html', () => {
|
||||||
expect(vaporHelpers).contains('setHtml')
|
expect(vaporHelpers).contains('setHtml')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
|
|
||||||
expect(ir.block.operation).toEqual([])
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
|
])
|
||||||
expect(ir.block.effect).toMatchObject([
|
expect(ir.block.effect).toMatchObject([
|
||||||
{
|
{
|
||||||
expressions: [
|
expressions: [
|
||||||
|
@ -70,7 +74,11 @@ describe('v-html', () => {
|
||||||
// children should have been removed
|
// children should have been removed
|
||||||
expect(ir.template).toEqual(['<div></div>'])
|
expect(ir.template).toEqual(['<div></div>'])
|
||||||
|
|
||||||
expect(ir.block.operation).toEqual([])
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
|
])
|
||||||
expect(ir.block.effect).toMatchObject([
|
expect(ir.block.effect).toMatchObject([
|
||||||
{
|
{
|
||||||
expressions: [
|
expressions: [
|
||||||
|
|
|
@ -47,6 +47,9 @@ describe('v-on', () => {
|
||||||
keyOverride: undefined,
|
keyOverride: undefined,
|
||||||
delegate: true,
|
delegate: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -91,7 +94,11 @@ describe('v-on', () => {
|
||||||
expect(vaporHelpers).contains('on')
|
expect(vaporHelpers).contains('on')
|
||||||
expect(vaporHelpers).contains('renderEffect')
|
expect(vaporHelpers).contains('renderEffect')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
expect(ir.block.operation).toEqual([])
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
expect(ir.block.effect[0].operations[0]).toMatchObject({
|
expect(ir.block.effect[0].operations[0]).toMatchObject({
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
|
@ -130,7 +137,11 @@ describe('v-on', () => {
|
||||||
expect(vaporHelpers).contains('on')
|
expect(vaporHelpers).contains('on')
|
||||||
expect(vaporHelpers).contains('renderEffect')
|
expect(vaporHelpers).contains('renderEffect')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
expect(ir.block.operation).toEqual([])
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
expect(ir.block.effect[0].operations[0]).toMatchObject({
|
expect(ir.block.effect[0].operations[0]).toMatchObject({
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
|
@ -169,6 +180,9 @@ describe('v-on', () => {
|
||||||
},
|
},
|
||||||
delegate: true,
|
delegate: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains(`_delegate(n0, "click", () => $event => (_ctx.i++))`)
|
expect(code).contains(`_delegate(n0, "click", () => $event => (_ctx.i++))`)
|
||||||
})
|
})
|
||||||
|
@ -206,6 +220,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: 'foo();bar()' },
|
value: { content: 'foo();bar()' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
// should wrap with `{` for multiple statements
|
// should wrap with `{` for multiple statements
|
||||||
// in this case the return value is discarded and the behavior is
|
// in this case the return value is discarded and the behavior is
|
||||||
|
@ -224,6 +241,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: '\nfoo();\nbar()\n' },
|
value: { content: '\nfoo();\nbar()\n' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
// should wrap with `{` for multiple statements
|
// should wrap with `{` for multiple statements
|
||||||
// in this case the return value is discarded and the behavior is
|
// in this case the return value is discarded and the behavior is
|
||||||
|
@ -244,6 +264,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: 'foo($event)' },
|
value: { content: 'foo($event)' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
// should NOT prefix $event
|
// should NOT prefix $event
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
|
@ -262,6 +285,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: 'foo($event);bar()' },
|
value: { content: 'foo($event);bar()' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
// should NOT prefix $event
|
// should NOT prefix $event
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
|
@ -278,6 +304,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: '$event => foo($event)' },
|
value: { content: '$event => foo($event)' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
`_delegate(n0, "click", () => $event => _ctx.foo($event))`,
|
`_delegate(n0, "click", () => $event => _ctx.foo($event))`,
|
||||||
|
@ -296,6 +325,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: '(e: any): any => foo(e)' },
|
value: { content: '(e: any): any => foo(e)' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
`_delegate(n0, "click", () => (e: any): any => _ctx.foo(e))`,
|
`_delegate(n0, "click", () => (e: any): any => _ctx.foo(e))`,
|
||||||
|
@ -323,6 +355,9 @@ describe('v-on', () => {
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -349,6 +384,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: `a['b' + c]` },
|
value: { content: `a['b' + c]` },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -361,6 +399,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: `a['b' + c]` },
|
value: { content: `a['b' + c]` },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -378,6 +419,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: `e => foo(e)` },
|
value: { content: `e => foo(e)` },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains(`_delegate(n0, "click", () => e => _ctx.foo(e))`)
|
expect(code).contains(`_delegate(n0, "click", () => e => _ctx.foo(e))`)
|
||||||
})
|
})
|
||||||
|
@ -432,6 +476,9 @@ describe('v-on', () => {
|
||||||
keyOverride: undefined,
|
keyOverride: undefined,
|
||||||
delegate: false,
|
delegate: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
`_on(n0, "click", () => _ctx.test, {
|
`_on(n0, "click", () => _ctx.test, {
|
||||||
|
@ -487,6 +534,9 @@ describe('v-on', () => {
|
||||||
options: [],
|
options: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -529,6 +579,9 @@ describe('v-on', () => {
|
||||||
options: ['capture'],
|
options: ['capture'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -543,6 +596,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
modifiers: { nonKeys: ['exact'] },
|
modifiers: { nonKeys: ['exact'] },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -562,6 +618,9 @@ describe('v-on', () => {
|
||||||
options: [],
|
options: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -604,6 +663,9 @@ describe('v-on', () => {
|
||||||
modifiers: { nonKeys: ['right'] },
|
modifiers: { nonKeys: ['right'] },
|
||||||
keyOverride: undefined,
|
keyOverride: undefined,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -645,6 +707,9 @@ describe('v-on', () => {
|
||||||
modifiers: { nonKeys: ['middle'] },
|
modifiers: { nonKeys: ['middle'] },
|
||||||
keyOverride: undefined,
|
keyOverride: undefined,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
|
@ -694,6 +759,9 @@ describe('v-on', () => {
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
delegate: true,
|
delegate: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -68,6 +68,7 @@ describe('compiler: v-once', () => {
|
||||||
elements: [0],
|
elements: [0],
|
||||||
parent: 2,
|
parent: 2,
|
||||||
},
|
},
|
||||||
|
{ type: IRNodeTypes.SET_INHERIT_ATTRS },
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -96,6 +97,9 @@ describe('compiler: v-once', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
expect(code).not.contains('effect')
|
expect(code).not.contains('effect')
|
||||||
})
|
})
|
||||||
|
@ -128,6 +132,9 @@ describe('compiler: v-once', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -147,6 +154,7 @@ describe('compiler: v-once', () => {
|
||||||
elements: [0],
|
elements: [0],
|
||||||
parent: 1,
|
parent: 1,
|
||||||
},
|
},
|
||||||
|
{ type: IRNodeTypes.SET_INHERIT_ATTRS },
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -160,7 +168,7 @@ describe('compiler: v-once', () => {
|
||||||
expect(code).toMatchSnapshot()
|
expect(code).toMatchSnapshot()
|
||||||
expect(helpers).lengthOf(0)
|
expect(helpers).lengthOf(0)
|
||||||
expect(ir.block.effect).lengthOf(0)
|
expect(ir.block.effect).lengthOf(0)
|
||||||
expect(ir.block.operation).lengthOf(0)
|
expect(ir.block.operation).lengthOf(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
test.todo('with hoistStatic: true')
|
test.todo('with hoistStatic: true')
|
||||||
|
|
|
@ -28,7 +28,11 @@ describe('v-text', () => {
|
||||||
expect(vaporHelpers).contains('setText')
|
expect(vaporHelpers).contains('setText')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
|
|
||||||
expect(ir.block.operation).toEqual([])
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
expect(ir.block.effect).toMatchObject([
|
expect(ir.block.effect).toMatchObject([
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {
|
||||||
genMulti,
|
genMulti,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
import { genPropKey } from './prop'
|
import { genPropKey, genPropValue } from './prop'
|
||||||
import {
|
import {
|
||||||
createSimpleExpression,
|
createSimpleExpression,
|
||||||
toValidAssetId,
|
toValidAssetId,
|
||||||
|
@ -121,14 +121,15 @@ function genStaticProps(
|
||||||
}
|
}
|
||||||
|
|
||||||
function genProp(prop: IRProp, context: CodegenContext, isStatic?: boolean) {
|
function genProp(prop: IRProp, context: CodegenContext, isStatic?: boolean) {
|
||||||
|
const values = genPropValue(prop.values, context)
|
||||||
return [
|
return [
|
||||||
...genPropKey(prop, context),
|
...genPropKey(prop, context),
|
||||||
': ',
|
': ',
|
||||||
...(prop.handler
|
...(prop.handler
|
||||||
? genEventHandler(context, prop.values[0])
|
? genEventHandler(context, prop.values[0])
|
||||||
: isStatic
|
: isStatic
|
||||||
? ['() => (', ...genExpression(prop.values[0], context), ')']
|
? ['() => (', ...values, ')']
|
||||||
: genExpression(prop.values[0], context)),
|
: values),
|
||||||
...(prop.model
|
...(prop.model
|
||||||
? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)]
|
? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)]
|
||||||
: []),
|
: []),
|
||||||
|
|
|
@ -132,7 +132,7 @@ function genIdentifier(
|
||||||
prefix = `${raw}: `
|
prefix = `${raw}: `
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = bindingMetadata[raw]
|
const type = bindingMetadata && bindingMetadata[raw]
|
||||||
if (inline) {
|
if (inline) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BindingTypes.SETUP_LET:
|
case BindingTypes.SETUP_LET:
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { genFor } from './for'
|
||||||
import { genSetHtml } from './html'
|
import { genSetHtml } from './html'
|
||||||
import { genIf } from './if'
|
import { genIf } from './if'
|
||||||
import { genSetModelValue } from './modelValue'
|
import { genSetModelValue } from './modelValue'
|
||||||
import { genDynamicProps, genSetProp } from './prop'
|
import { genDynamicProps, genSetInheritAttrs, genSetProp } from './prop'
|
||||||
import { genDeclareOldRef, genSetTemplateRef } from './templateRef'
|
import { genDeclareOldRef, genSetTemplateRef } from './templateRef'
|
||||||
import { genCreateTextNode, genSetText } from './text'
|
import { genCreateTextNode, genSetText } from './text'
|
||||||
import {
|
import {
|
||||||
|
@ -67,6 +67,8 @@ export function genOperation(
|
||||||
return genDeclareOldRef(oper)
|
return genDeclareOldRef(oper)
|
||||||
case IRNodeTypes.SLOT_OUTLET_NODE:
|
case IRNodeTypes.SLOT_OUTLET_NODE:
|
||||||
return genSlotOutlet(oper, context)
|
return genSlotOutlet(oper, context)
|
||||||
|
case IRNodeTypes.SET_INHERIT_ATTRS:
|
||||||
|
return genSetInheritAttrs(oper, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
IRDynamicPropsKind,
|
IRDynamicPropsKind,
|
||||||
type IRProp,
|
type IRProp,
|
||||||
type SetDynamicPropsIRNode,
|
type SetDynamicPropsIRNode,
|
||||||
|
type SetInheritAttrsIRNode,
|
||||||
type SetPropIRNode,
|
type SetPropIRNode,
|
||||||
type VaporHelper,
|
type VaporHelper,
|
||||||
} from '../ir'
|
} from '../ir'
|
||||||
|
@ -55,6 +56,7 @@ export function genSetProp(
|
||||||
`n${oper.element}`,
|
`n${oper.element}`,
|
||||||
omitKey ? false : genExpression(key, context),
|
omitKey ? false : genExpression(key, context),
|
||||||
genPropValue(values, context),
|
genPropValue(values, context),
|
||||||
|
oper.root && 'true',
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -70,14 +72,18 @@ export function genDynamicProps(
|
||||||
...genCall(
|
...genCall(
|
||||||
vaporHelper('setDynamicProps'),
|
vaporHelper('setDynamicProps'),
|
||||||
`n${oper.element}`,
|
`n${oper.element}`,
|
||||||
...oper.props.map(
|
genMulti(
|
||||||
props =>
|
DELIMITERS_ARRAY,
|
||||||
Array.isArray(props)
|
...oper.props.map(
|
||||||
? genLiteralObjectProps(props, context) // static and dynamic arg props
|
props =>
|
||||||
: props.kind === IRDynamicPropsKind.ATTRIBUTE
|
Array.isArray(props)
|
||||||
? genLiteralObjectProps([props], context) // dynamic arg props
|
? genLiteralObjectProps(props, context) // static and dynamic arg props
|
||||||
: genExpression(props.value, context), // v-bind=""
|
: props.kind === IRDynamicPropsKind.ATTRIBUTE
|
||||||
|
? genLiteralObjectProps([props], context) // dynamic arg props
|
||||||
|
: genExpression(props.value, context), // v-bind=""
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
oper.root && 'true',
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -125,7 +131,10 @@ export function genPropKey(
|
||||||
return ['[', modifier && `${JSON.stringify(modifier)} + `, ...key, ']']
|
return ['[', modifier && `${JSON.stringify(modifier)} + `, ...key, ']']
|
||||||
}
|
}
|
||||||
|
|
||||||
function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) {
|
export function genPropValue(
|
||||||
|
values: SimpleExpressionNode[],
|
||||||
|
context: CodegenContext,
|
||||||
|
): CodeFragment[] {
|
||||||
if (values.length === 1) {
|
if (values.length === 1) {
|
||||||
return genExpression(values[0], context)
|
return genExpression(values[0], context)
|
||||||
}
|
}
|
||||||
|
@ -134,3 +143,28 @@ function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) {
|
||||||
...values.map(expr => genExpression(expr, context)),
|
...values.map(expr => genExpression(expr, context)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function genSetInheritAttrs(
|
||||||
|
{ staticProps, dynamicProps }: SetInheritAttrsIRNode,
|
||||||
|
context: CodegenContext,
|
||||||
|
): CodeFragment[] {
|
||||||
|
const { vaporHelper } = context
|
||||||
|
|
||||||
|
// - `undefined` : no props
|
||||||
|
// - `false` : all props are static
|
||||||
|
// - `string[]` : list of props are dynamic
|
||||||
|
// - `true` : all props as dynamic
|
||||||
|
const value =
|
||||||
|
dynamicProps === true
|
||||||
|
? 'true'
|
||||||
|
: dynamicProps.length
|
||||||
|
? genMulti(
|
||||||
|
DELIMITERS_ARRAY,
|
||||||
|
...dynamicProps.map(p => JSON.stringify(p)),
|
||||||
|
)
|
||||||
|
: staticProps
|
||||||
|
? 'false'
|
||||||
|
: null
|
||||||
|
if (value == null) return []
|
||||||
|
return [NEWLINE, ...genCall(vaporHelper('setInheritAttrs'), value)]
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ export function genMulti(
|
||||||
...frags: CodeFragments[]
|
...frags: CodeFragments[]
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
if (placeholder) {
|
if (placeholder) {
|
||||||
while (!frags[frags.length - 1]) {
|
while (frags.length > 0 && !frags[frags.length - 1]) {
|
||||||
frags.pop()
|
frags.pop()
|
||||||
}
|
}
|
||||||
frags = frags.map(frag => frag || placeholder)
|
frags = frags.map(frag => frag || placeholder)
|
||||||
|
|
|
@ -24,6 +24,7 @@ export enum IRNodeTypes {
|
||||||
SET_HTML,
|
SET_HTML,
|
||||||
SET_TEMPLATE_REF,
|
SET_TEMPLATE_REF,
|
||||||
SET_MODEL_VALUE,
|
SET_MODEL_VALUE,
|
||||||
|
SET_INHERIT_ATTRS,
|
||||||
|
|
||||||
INSERT_NODE,
|
INSERT_NODE,
|
||||||
PREPEND_NODE,
|
PREPEND_NODE,
|
||||||
|
@ -93,12 +94,14 @@ export interface SetPropIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_PROP
|
type: IRNodeTypes.SET_PROP
|
||||||
element: number
|
element: number
|
||||||
prop: IRProp
|
prop: IRProp
|
||||||
|
root: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetDynamicPropsIRNode extends BaseIRNode {
|
export interface SetDynamicPropsIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_DYNAMIC_PROPS
|
type: IRNodeTypes.SET_DYNAMIC_PROPS
|
||||||
element: number
|
element: number
|
||||||
props: IRProps[]
|
props: IRProps[]
|
||||||
|
root: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetDynamicEventsIRNode extends BaseIRNode {
|
export interface SetDynamicEventsIRNode extends BaseIRNode {
|
||||||
|
@ -156,6 +159,12 @@ export interface SetModelValueIRNode extends BaseIRNode {
|
||||||
isComponent: boolean
|
isComponent: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SetInheritAttrsIRNode extends BaseIRNode {
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS
|
||||||
|
staticProps: boolean
|
||||||
|
dynamicProps: true | string[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreateTextNodeIRNode extends BaseIRNode {
|
export interface CreateTextNodeIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.CREATE_TEXT_NODE
|
type: IRNodeTypes.CREATE_TEXT_NODE
|
||||||
id: number
|
id: number
|
||||||
|
@ -220,6 +229,7 @@ export type OperationNode =
|
||||||
| SetHtmlIRNode
|
| SetHtmlIRNode
|
||||||
| SetTemplateRefIRNode
|
| SetTemplateRefIRNode
|
||||||
| SetModelValueIRNode
|
| SetModelValueIRNode
|
||||||
|
| SetInheritAttrsIRNode
|
||||||
| CreateTextNodeIRNode
|
| CreateTextNodeIRNode
|
||||||
| InsertNodeIRNode
|
| InsertNodeIRNode
|
||||||
| PrependNodeIRNode
|
| PrependNodeIRNode
|
||||||
|
|
|
@ -64,9 +64,15 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||||
isDynamicComponent,
|
isDynamicComponent,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const singleRoot =
|
||||||
|
context.root === context.parent &&
|
||||||
|
context.parent.node.children.filter(
|
||||||
|
child => child.type !== NodeTypes.COMMENT,
|
||||||
|
).length === 1
|
||||||
;(isComponent ? transformComponentElement : transformNativeElement)(
|
;(isComponent ? transformComponentElement : transformNativeElement)(
|
||||||
node as any,
|
node as any,
|
||||||
propsResult,
|
propsResult,
|
||||||
|
singleRoot,
|
||||||
context as TransformContext<ElementNode>,
|
context as TransformContext<ElementNode>,
|
||||||
isDynamicComponent,
|
isDynamicComponent,
|
||||||
)
|
)
|
||||||
|
@ -76,6 +82,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||||
function transformComponentElement(
|
function transformComponentElement(
|
||||||
node: ComponentNode,
|
node: ComponentNode,
|
||||||
propsResult: PropsResult,
|
propsResult: PropsResult,
|
||||||
|
singleRoot: boolean,
|
||||||
context: TransformContext,
|
context: TransformContext,
|
||||||
isDynamicComponent: boolean,
|
isDynamicComponent: boolean,
|
||||||
) {
|
) {
|
||||||
|
@ -108,16 +115,13 @@ function transformComponentElement(
|
||||||
}
|
}
|
||||||
|
|
||||||
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
|
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
|
||||||
const root =
|
|
||||||
context.root === context.parent && context.parent.node.children.length === 1
|
|
||||||
|
|
||||||
context.registerOperation({
|
context.registerOperation({
|
||||||
type: IRNodeTypes.CREATE_COMPONENT_NODE,
|
type: IRNodeTypes.CREATE_COMPONENT_NODE,
|
||||||
id: context.reference(),
|
id: context.reference(),
|
||||||
tag,
|
tag,
|
||||||
props: propsResult[0] ? propsResult[1] : [propsResult[1]],
|
props: propsResult[0] ? propsResult[1] : [propsResult[1]],
|
||||||
asset,
|
asset,
|
||||||
root,
|
root: singleRoot,
|
||||||
slots: [...context.slots],
|
slots: [...context.slots],
|
||||||
once: context.inVOnce,
|
once: context.inVOnce,
|
||||||
dynamic: dynamicComponent,
|
dynamic: dynamicComponent,
|
||||||
|
@ -162,6 +166,7 @@ function resolveSetupReference(name: string, context: TransformContext) {
|
||||||
function transformNativeElement(
|
function transformNativeElement(
|
||||||
node: PlainElementNode,
|
node: PlainElementNode,
|
||||||
propsResult: PropsResult,
|
propsResult: PropsResult,
|
||||||
|
singleRoot: boolean,
|
||||||
context: TransformContext<ElementNode>,
|
context: TransformContext<ElementNode>,
|
||||||
) {
|
) {
|
||||||
const { tag } = node
|
const { tag } = node
|
||||||
|
@ -172,29 +177,43 @@ function transformNativeElement(
|
||||||
template += `<${tag}`
|
template += `<${tag}`
|
||||||
if (scopeId) template += ` ${scopeId}`
|
if (scopeId) template += ` ${scopeId}`
|
||||||
|
|
||||||
|
let staticProps = false
|
||||||
|
const dynamicProps: string[] = []
|
||||||
if (propsResult[0] /* dynamic props */) {
|
if (propsResult[0] /* dynamic props */) {
|
||||||
const [, dynamicArgs, expressions] = propsResult
|
const [, dynamicArgs, expressions] = propsResult
|
||||||
context.registerEffect(expressions, {
|
context.registerEffect(expressions, {
|
||||||
type: IRNodeTypes.SET_DYNAMIC_PROPS,
|
type: IRNodeTypes.SET_DYNAMIC_PROPS,
|
||||||
element: context.reference(),
|
element: context.reference(),
|
||||||
props: dynamicArgs,
|
props: dynamicArgs,
|
||||||
|
root: singleRoot,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
for (const prop of propsResult[1]) {
|
for (const prop of propsResult[1]) {
|
||||||
const { key, values } = prop
|
const { key, values } = prop
|
||||||
if (key.isStatic && values.length === 1 && values[0].isStatic) {
|
if (key.isStatic && values.length === 1 && values[0].isStatic) {
|
||||||
|
staticProps = true
|
||||||
template += ` ${key.content}`
|
template += ` ${key.content}`
|
||||||
if (values[0].content) template += `="${values[0].content}"`
|
if (values[0].content) template += `="${values[0].content}"`
|
||||||
} else {
|
} else {
|
||||||
|
dynamicProps.push(key.content)
|
||||||
context.registerEffect(values, {
|
context.registerEffect(values, {
|
||||||
type: IRNodeTypes.SET_PROP,
|
type: IRNodeTypes.SET_PROP,
|
||||||
element: context.reference(),
|
element: context.reference(),
|
||||||
prop,
|
prop,
|
||||||
|
root: singleRoot,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (singleRoot) {
|
||||||
|
context.registerOperation({
|
||||||
|
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||||
|
staticProps: staticProps,
|
||||||
|
dynamicProps: propsResult[0] ? true : dynamicProps,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
template += `>` + context.childrenTemplate.join('')
|
template += `>` + context.childrenTemplate.join('')
|
||||||
// TODO remove unnecessary close tag, e.g. if it's the last element of the template
|
// TODO remove unnecessary close tag, e.g. if it's the last element of the template
|
||||||
if (!isVoidTag(tag)) {
|
if (!isVoidTag(tag)) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
ref,
|
ref,
|
||||||
renderEffect,
|
renderEffect,
|
||||||
setDynamicProps,
|
setDynamicProps,
|
||||||
|
setInheritAttrs,
|
||||||
template,
|
template,
|
||||||
watchEffect,
|
watchEffect,
|
||||||
} from '../src'
|
} from '../src'
|
||||||
|
@ -77,9 +78,7 @@ describe('api: setup context', () => {
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup(props, { attrs }) {
|
setup(props, { attrs }) {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
renderEffect(() => {
|
renderEffect(() => setDynamicProps(el, [attrs]))
|
||||||
setDynamicProps(el, attrs)
|
|
||||||
})
|
|
||||||
return el
|
return el
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -103,23 +102,24 @@ describe('api: setup context', () => {
|
||||||
const toggle = ref(true)
|
const toggle = ref(true)
|
||||||
|
|
||||||
const Wrapper = defineComponent({
|
const Wrapper = defineComponent({
|
||||||
setup(_, { slots }) {
|
setup(_) {
|
||||||
return slots.default!()
|
const n0 = createSlot('default')
|
||||||
|
setInheritAttrs(false, true)
|
||||||
|
return n0
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const Child = defineComponent({
|
const Child = defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup(_: any, { attrs }: any) {
|
setup(_: any, { attrs }: any) {
|
||||||
return createComponent(Wrapper, null, {
|
const n0 = createComponent(Wrapper, null, {
|
||||||
default: () => {
|
default: () => {
|
||||||
const n0 = template('<div>')() as HTMLDivElement
|
const n0 = template('<div>')() as HTMLDivElement
|
||||||
renderEffect(() => {
|
renderEffect(() => setDynamicProps(n0, [attrs], true))
|
||||||
setDynamicProps(n0, attrs)
|
|
||||||
})
|
|
||||||
return n0
|
return n0
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
return n0
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
nextTick,
|
nextTick,
|
||||||
ref,
|
ref,
|
||||||
|
setInheritAttrs,
|
||||||
setText,
|
setText,
|
||||||
template,
|
template,
|
||||||
watchEffect,
|
watchEffect,
|
||||||
|
@ -18,7 +19,8 @@ describe('attribute fallthrough', () => {
|
||||||
props: ['foo'],
|
props: ['foo'],
|
||||||
render() {
|
render() {
|
||||||
const instance = getCurrentInstance()!
|
const instance = getCurrentInstance()!
|
||||||
const n0 = t0()
|
const n0 = t0() as Element
|
||||||
|
setInheritAttrs()
|
||||||
watchEffect(() => setText(n0, instance.props.foo))
|
watchEffect(() => setText(n0, instance.props.foo))
|
||||||
return n0
|
return n0
|
||||||
},
|
},
|
||||||
|
@ -62,7 +64,8 @@ describe('attribute fallthrough', () => {
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
render() {
|
render() {
|
||||||
const instance = getCurrentInstance()!
|
const instance = getCurrentInstance()!
|
||||||
const n0 = t0()
|
const n0 = t0() as Element
|
||||||
|
setInheritAttrs()
|
||||||
watchEffect(() => setText(n0, instance.props.foo))
|
watchEffect(() => setText(n0, instance.props.foo))
|
||||||
return n0
|
return n0
|
||||||
},
|
},
|
||||||
|
@ -105,7 +108,8 @@ describe('attribute fallthrough', () => {
|
||||||
props: ['custom-attr'],
|
props: ['custom-attr'],
|
||||||
render() {
|
render() {
|
||||||
const instance = getCurrentInstance()!
|
const instance = getCurrentInstance()!
|
||||||
const n0 = t0()
|
const n0 = t0() as Element
|
||||||
|
setInheritAttrs()
|
||||||
watchEffect(() => setText(n0, instance.attrs.foo))
|
watchEffect(() => setText(n0, instance.attrs.foo))
|
||||||
return n0
|
return n0
|
||||||
},
|
},
|
||||||
|
|
|
@ -407,25 +407,25 @@ describe('patchProp', () => {
|
||||||
describe('setDynamicProps', () => {
|
describe('setDynamicProps', () => {
|
||||||
test('basic set dynamic props', () => {
|
test('basic set dynamic props', () => {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
setDynamicProps(el, { foo: 'val' }, { bar: 'val' })
|
setDynamicProps(el, [{ foo: 'val' }, { bar: 'val' }])
|
||||||
expect(el.getAttribute('foo')).toBe('val')
|
expect(el.getAttribute('foo')).toBe('val')
|
||||||
expect(el.getAttribute('bar')).toBe('val')
|
expect(el.getAttribute('bar')).toBe('val')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should merge props', () => {
|
test('should merge props', () => {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
setDynamicProps(el, { foo: 'val' }, { foo: 'newVal' })
|
setDynamicProps(el, [{ foo: 'val' }, { foo: 'newVal' }])
|
||||||
expect(el.getAttribute('foo')).toBe('newVal')
|
expect(el.getAttribute('foo')).toBe('newVal')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should reset old props', () => {
|
test('should reset old props', () => {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
|
|
||||||
setDynamicProps(el, { foo: 'val' })
|
setDynamicProps(el, [{ foo: 'val' }])
|
||||||
expect(el.attributes.length).toBe(1)
|
expect(el.attributes.length).toBe(1)
|
||||||
expect(el.getAttribute('foo')).toBe('val')
|
expect(el.getAttribute('foo')).toBe('val')
|
||||||
|
|
||||||
setDynamicProps(el, { bar: 'val' })
|
setDynamicProps(el, [{ bar: 'val' }])
|
||||||
expect(el.attributes.length).toBe(1)
|
expect(el.attributes.length).toBe(1)
|
||||||
expect(el.getAttribute('bar')).toBe('val')
|
expect(el.getAttribute('bar')).toBe('val')
|
||||||
expect(el.getAttribute('foo')).toBeNull()
|
expect(el.getAttribute('foo')).toBeNull()
|
||||||
|
@ -434,18 +434,18 @@ describe('patchProp', () => {
|
||||||
test('should reset old modifier props', () => {
|
test('should reset old modifier props', () => {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
|
|
||||||
setDynamicProps(el, { ['.foo']: 'val' })
|
setDynamicProps(el, [{ ['.foo']: 'val' }])
|
||||||
expect((el as any).foo).toBe('val')
|
expect((el as any).foo).toBe('val')
|
||||||
|
|
||||||
setDynamicProps(el, { ['.bar']: 'val' })
|
setDynamicProps(el, [{ ['.bar']: 'val' }])
|
||||||
expect((el as any).bar).toBe('val')
|
expect((el as any).bar).toBe('val')
|
||||||
expect((el as any).foo).toBe('')
|
expect((el as any).foo).toBe('')
|
||||||
|
|
||||||
setDynamicProps(el, { ['^foo']: 'val' })
|
setDynamicProps(el, [{ ['^foo']: 'val' }])
|
||||||
expect(el.attributes.length).toBe(1)
|
expect(el.attributes.length).toBe(1)
|
||||||
expect(el.getAttribute('foo')).toBe('val')
|
expect(el.getAttribute('foo')).toBe('val')
|
||||||
|
|
||||||
setDynamicProps(el, { ['^bar']: 'val' })
|
setDynamicProps(el, [{ ['^bar']: 'val' }])
|
||||||
expect(el.attributes.length).toBe(1)
|
expect(el.attributes.length).toBe(1)
|
||||||
expect(el.getAttribute('bar')).toBe('val')
|
expect(el.getAttribute('bar')).toBe('val')
|
||||||
expect(el.getAttribute('foo')).toBeNull()
|
expect(el.getAttribute('foo')).toBeNull()
|
||||||
|
|
|
@ -12,11 +12,12 @@ import {
|
||||||
walkRawProps,
|
walkRawProps,
|
||||||
} from './componentProps'
|
} from './componentProps'
|
||||||
import { type RawSlots, isDynamicSlotFn } from './componentSlots'
|
import { type RawSlots, isDynamicSlotFn } from './componentSlots'
|
||||||
import { withAttrs } from './componentAttrs'
|
import { setInheritAttrs, withAttrs } from './componentAttrs'
|
||||||
import { isString } from '@vue/shared'
|
import { isString } from '@vue/shared'
|
||||||
import { renderEffect } from './renderEffect'
|
import { renderEffect } from './renderEffect'
|
||||||
import { normalizeBlock } from './dom/element'
|
import { normalizeBlock } from './dom/element'
|
||||||
import { setDynamicProp } from './dom/prop'
|
import { setClass, setDynamicProp } from './dom/prop'
|
||||||
|
import { setStyle } from './dom/style'
|
||||||
|
|
||||||
export function createComponent(
|
export function createComponent(
|
||||||
comp: Component | string,
|
comp: Component | string,
|
||||||
|
@ -25,11 +26,12 @@ export function createComponent(
|
||||||
singleRoot: boolean = false,
|
singleRoot: boolean = false,
|
||||||
once: boolean = false,
|
once: boolean = false,
|
||||||
): ComponentInternalInstance | HTMLElement {
|
): ComponentInternalInstance | HTMLElement {
|
||||||
|
const current = currentInstance!
|
||||||
|
|
||||||
if (isString(comp)) {
|
if (isString(comp)) {
|
||||||
return fallbackComponent(comp, rawProps, slots)
|
return fallbackComponent(comp, rawProps, slots, current, singleRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
const current = currentInstance!
|
|
||||||
const instance = createComponentInstance(
|
const instance = createComponentInstance(
|
||||||
comp,
|
comp,
|
||||||
singleRoot ? withAttrs(rawProps) : rawProps,
|
singleRoot ? withAttrs(rawProps) : rawProps,
|
||||||
|
@ -48,16 +50,31 @@ function fallbackComponent(
|
||||||
comp: string,
|
comp: string,
|
||||||
rawProps: RawProps | null,
|
rawProps: RawProps | null,
|
||||||
slots: RawSlots | null,
|
slots: RawSlots | null,
|
||||||
|
instance: ComponentInternalInstance,
|
||||||
|
singleRoot: boolean = false,
|
||||||
): HTMLElement {
|
): HTMLElement {
|
||||||
// eslint-disable-next-line no-restricted-globals
|
// eslint-disable-next-line no-restricted-globals
|
||||||
const el = document.createElement(comp)
|
const el = document.createElement(comp)
|
||||||
|
|
||||||
if (rawProps) {
|
if (rawProps || Object.keys(instance.attrs).length) {
|
||||||
rawProps = normalizeRawProps(rawProps)
|
rawProps = [() => instance.attrs, ...normalizeRawProps(rawProps)]
|
||||||
|
|
||||||
renderEffect(() => {
|
renderEffect(() => {
|
||||||
walkRawProps(rawProps as NormalizedRawProps, (key, value, getter) => {
|
let classes: unknown[] | undefined
|
||||||
setDynamicProp(el, key, getter ? value() : value)
|
let styles: unknown[] | undefined
|
||||||
})
|
|
||||||
|
walkRawProps(
|
||||||
|
rawProps as NormalizedRawProps,
|
||||||
|
(key, valueOrGetter, getter) => {
|
||||||
|
const value = getter ? valueOrGetter() : valueOrGetter
|
||||||
|
if (key === 'class') (classes ||= []).push(value)
|
||||||
|
else if (key === 'style') (styles ||= []).push(value)
|
||||||
|
else setDynamicProp(el, key, value)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (classes) setClass(el, classes)
|
||||||
|
if (styles) setStyle(el, styles)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,5 +89,9 @@ function fallbackComponent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (singleRoot) {
|
||||||
|
setInheritAttrs(true)
|
||||||
|
}
|
||||||
|
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@ import {
|
||||||
shallowReadonly,
|
shallowReadonly,
|
||||||
} from '@vue/reactivity'
|
} from '@vue/reactivity'
|
||||||
import { isArray, isFunction, isObject } from '@vue/shared'
|
import { isArray, isFunction, isObject } from '@vue/shared'
|
||||||
import { fallThroughAttrs } from './componentAttrs'
|
|
||||||
import { VaporErrorCodes, callWithErrorHandling } from './errorHandling'
|
import { VaporErrorCodes, callWithErrorHandling } from './errorHandling'
|
||||||
import { endMeasure, startMeasure } from './profiling'
|
import { endMeasure, startMeasure } from './profiling'
|
||||||
import { devtoolsComponentAdded } from './devtools'
|
import { devtoolsComponentAdded } from './devtools'
|
||||||
|
import { fallThroughAttrs } from './componentAttrs'
|
||||||
|
|
||||||
export const fragmentKey: unique symbol = Symbol(__DEV__ ? `fragmentKey` : ``)
|
export const fragmentKey: unique symbol = Symbol(__DEV__ ? `fragmentKey` : ``)
|
||||||
|
|
||||||
|
@ -86,9 +86,6 @@ export function setupComponent(instance: ComponentInternalInstance): void {
|
||||||
resetTracking()
|
resetTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block instanceof DocumentFragment) {
|
|
||||||
block = Array.from(block.childNodes)
|
|
||||||
}
|
|
||||||
if (!block) {
|
if (!block) {
|
||||||
// TODO: warn no template
|
// TODO: warn no template
|
||||||
block = []
|
block = []
|
||||||
|
|
|
@ -174,6 +174,13 @@ export interface ComponentInternalInstance {
|
||||||
emit: EmitFn
|
emit: EmitFn
|
||||||
emitted: Record<string, boolean> | null
|
emitted: Record<string, boolean> | null
|
||||||
attrs: Data
|
attrs: Data
|
||||||
|
/**
|
||||||
|
* - `undefined` : no props
|
||||||
|
* - `false` : all props are static
|
||||||
|
* - `string[]` : list of props are dynamic
|
||||||
|
* - `true` : all props as dynamic
|
||||||
|
*/
|
||||||
|
dynamicAttrs?: string[] | boolean
|
||||||
slots: StaticSlots
|
slots: StaticSlots
|
||||||
refs: Data
|
refs: Data
|
||||||
// exposed properties via expose()
|
// exposed properties via expose()
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import { camelize, isArray } from '@vue/shared'
|
import { camelize, isArray, normalizeClass, normalizeStyle } from '@vue/shared'
|
||||||
import { type ComponentInternalInstance, currentInstance } from './component'
|
import { type ComponentInternalInstance, currentInstance } from './component'
|
||||||
import { isEmitListener } from './componentEmits'
|
import { isEmitListener } from './componentEmits'
|
||||||
import { setDynamicProps } from './dom/prop'
|
|
||||||
import { type RawProps, walkRawProps } from './componentProps'
|
import { type RawProps, walkRawProps } from './componentProps'
|
||||||
import { renderEffect } from './renderEffect'
|
import { renderEffect } from './renderEffect'
|
||||||
|
import { mergeProp, setDynamicProp } from './dom/prop'
|
||||||
|
|
||||||
export function patchAttrs(instance: ComponentInternalInstance): void {
|
export function patchAttrs(
|
||||||
|
instance: ComponentInternalInstance,
|
||||||
|
hasDynamicProps?: boolean,
|
||||||
|
): void {
|
||||||
const {
|
const {
|
||||||
attrs,
|
attrs,
|
||||||
rawProps,
|
rawProps,
|
||||||
|
@ -14,6 +17,8 @@ export function patchAttrs(instance: ComponentInternalInstance): void {
|
||||||
|
|
||||||
if (!rawProps.length) return
|
if (!rawProps.length) return
|
||||||
const keys = new Set<string>()
|
const keys = new Set<string>()
|
||||||
|
const classes: any[] = []
|
||||||
|
const styles: any[] = []
|
||||||
|
|
||||||
walkRawProps(rawProps, registerAttr)
|
walkRawProps(rawProps, registerAttr)
|
||||||
for (const key in attrs) {
|
for (const key in attrs) {
|
||||||
|
@ -22,14 +27,42 @@ export function patchAttrs(instance: ComponentInternalInstance): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setClassOrStyle(classes, 'class', normalizeClass)
|
||||||
|
setClassOrStyle(styles, 'style', normalizeStyle)
|
||||||
|
|
||||||
|
function setClassOrStyle(
|
||||||
|
values: any[],
|
||||||
|
field: 'class' | 'style',
|
||||||
|
normalize: (value: any) => any,
|
||||||
|
) {
|
||||||
|
if (values.length) {
|
||||||
|
if (hasDynamicProps) {
|
||||||
|
Object.defineProperty(attrs, field, {
|
||||||
|
get() {
|
||||||
|
return normalize(values.map(value => value()))
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
attrs[field] = normalizeClass(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function registerAttr(key: string, value: any, getter?: boolean) {
|
function registerAttr(key: string, value: any, getter?: boolean) {
|
||||||
if (
|
if (
|
||||||
(!options || !(camelize(key) in options)) &&
|
(!options || !(camelize(key) in options)) &&
|
||||||
!isEmitListener(instance.emitsOptions, key) &&
|
!isEmitListener(instance.emitsOptions, key) &&
|
||||||
!keys.has(key)
|
(key === 'class' || key === 'style' || !keys.has(key))
|
||||||
) {
|
) {
|
||||||
keys.add(key)
|
keys.add(key)
|
||||||
if (getter) {
|
|
||||||
|
if (key === 'class' || key === 'style') {
|
||||||
|
;(key === 'class' ? classes : styles).push(
|
||||||
|
hasDynamicProps ? (getter ? value : () => value) : value,
|
||||||
|
)
|
||||||
|
} else if (getter) {
|
||||||
Object.defineProperty(attrs, key, {
|
Object.defineProperty(attrs, key, {
|
||||||
get: value,
|
get: value,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
|
@ -57,16 +90,47 @@ export function fallThroughAttrs(instance: ComponentInternalInstance): void {
|
||||||
const {
|
const {
|
||||||
block,
|
block,
|
||||||
type: { inheritAttrs },
|
type: { inheritAttrs },
|
||||||
|
dynamicAttrs,
|
||||||
} = instance
|
} = instance
|
||||||
if (inheritAttrs === false) return
|
if (
|
||||||
|
inheritAttrs === false ||
|
||||||
|
!(block instanceof Element) ||
|
||||||
|
// all props as dynamic
|
||||||
|
dynamicAttrs === true
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if (block instanceof Element) {
|
const hasStaticAttrs = dynamicAttrs || dynamicAttrs === false
|
||||||
|
|
||||||
|
let initial: Record<string, string> | undefined
|
||||||
|
if (hasStaticAttrs) {
|
||||||
// attrs in static template
|
// attrs in static template
|
||||||
const initial: Record<string, string> = {}
|
initial = {}
|
||||||
for (let i = 0; i < block.attributes.length; i++) {
|
for (let i = 0; i < block.attributes.length; i++) {
|
||||||
const attr = block.attributes[i]
|
const attr = block.attributes[i]
|
||||||
|
if (dynamicAttrs && dynamicAttrs.includes(attr.name)) continue
|
||||||
initial[attr.name] = attr.value
|
initial[attr.name] = attr.value
|
||||||
}
|
}
|
||||||
renderEffect(() => setDynamicProps(block, instance.attrs, initial))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderEffect(() => {
|
||||||
|
for (const key in instance.attrs) {
|
||||||
|
if (dynamicAttrs && dynamicAttrs.includes(key)) continue
|
||||||
|
|
||||||
|
let value: unknown
|
||||||
|
if (hasStaticAttrs) {
|
||||||
|
value = mergeProp(key, instance.attrs[key], initial![key])
|
||||||
|
} else {
|
||||||
|
value = instance.attrs[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
setDynamicProp(block, key, value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setInheritAttrs(dynamicAttrs?: string[] | boolean): void {
|
||||||
|
const instance = currentInstance!
|
||||||
|
if (instance.type.inheritAttrs === false) return
|
||||||
|
instance.dynamicAttrs = dynamicAttrs
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ export function initProps(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasDynamicProps) {
|
if (hasDynamicProps) {
|
||||||
firstEffect(instance, () => patchAttrs(instance))
|
firstEffect(instance, () => patchAttrs(instance, true))
|
||||||
} else {
|
} else {
|
||||||
patchAttrs(instance)
|
patchAttrs(instance)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,20 @@ import {
|
||||||
} from '../componentMetadata'
|
} from '../componentMetadata'
|
||||||
import { on } from './event'
|
import { on } from './event'
|
||||||
import type { Data } from '@vue/runtime-shared'
|
import type { Data } from '@vue/runtime-shared'
|
||||||
|
import { currentInstance } from '../component'
|
||||||
|
|
||||||
|
export function mergeInheritAttr(key: string, value: any): unknown {
|
||||||
|
const instance = currentInstance!
|
||||||
|
return mergeProp(key, instance.attrs[key], value)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setClass(el: Element, value: any, root?: boolean): void {
|
||||||
|
const prev = recordPropMetadata(
|
||||||
|
el,
|
||||||
|
'class',
|
||||||
|
(value = normalizeClass(root ? mergeInheritAttr('class', value) : value)),
|
||||||
|
)
|
||||||
|
|
||||||
export function setClass(el: Element, value: any): void {
|
|
||||||
const prev = recordPropMetadata(el, 'class', (value = normalizeClass(value)))
|
|
||||||
if (value !== prev && (value || prev)) {
|
if (value !== prev && (value || prev)) {
|
||||||
el.className = value
|
el.className = value
|
||||||
}
|
}
|
||||||
|
@ -132,8 +143,15 @@ export function setDynamicProp(el: Element, key: string, value: any): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setDynamicProps(el: Element, ...args: any): void {
|
export function setDynamicProps(
|
||||||
|
el: Element,
|
||||||
|
args: any[],
|
||||||
|
root?: boolean,
|
||||||
|
): void {
|
||||||
const oldProps = getMetadata(el)[MetadataKind.prop]
|
const oldProps = getMetadata(el)[MetadataKind.prop]
|
||||||
|
if (root) {
|
||||||
|
args.unshift(currentInstance!.attrs)
|
||||||
|
}
|
||||||
const props = args.length > 1 ? mergeProps(...args) : args[0]
|
const props = args.length > 1 ? mergeProps(...args) : args[0]
|
||||||
|
|
||||||
for (const key in oldProps) {
|
for (const key in oldProps) {
|
||||||
|
@ -153,32 +171,36 @@ export function setDynamicProps(el: Element, ...args: any): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO copied from runtime-core
|
export function mergeProp(
|
||||||
|
key: string,
|
||||||
|
existing: unknown,
|
||||||
|
incoming: unknown,
|
||||||
|
): unknown {
|
||||||
|
if (key === 'class') {
|
||||||
|
if (existing !== incoming) {
|
||||||
|
return normalizeClass([existing, incoming])
|
||||||
|
}
|
||||||
|
} else if (key === 'style') {
|
||||||
|
return normalizeStyle([existing, incoming])
|
||||||
|
} else if (isOn(key)) {
|
||||||
|
if (
|
||||||
|
incoming &&
|
||||||
|
existing !== incoming &&
|
||||||
|
!(isArray(existing) && existing.includes(incoming))
|
||||||
|
) {
|
||||||
|
return existing ? [].concat(existing as any, incoming as any) : incoming
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return incoming
|
||||||
|
}
|
||||||
|
|
||||||
export function mergeProps(...args: Data[]): Data {
|
export function mergeProps(...args: Data[]): Data {
|
||||||
const ret: Data = {}
|
const ret: Data = {}
|
||||||
for (let i = 0; i < args.length; i++) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
const toMerge = args[i]
|
const toMerge = args[i]
|
||||||
for (const key in toMerge) {
|
for (const key in toMerge) {
|
||||||
if (key === 'class') {
|
if (key !== '') {
|
||||||
if (ret.class !== toMerge.class) {
|
ret[key] = mergeProp(key, ret[key], toMerge[key])
|
||||||
ret.class = normalizeClass([ret.class, toMerge.class])
|
|
||||||
}
|
|
||||||
} else if (key === 'style') {
|
|
||||||
ret.style = normalizeStyle([ret.style, toMerge.style])
|
|
||||||
} else if (isOn(key)) {
|
|
||||||
const existing = ret[key]
|
|
||||||
const incoming = toMerge[key]
|
|
||||||
if (
|
|
||||||
incoming &&
|
|
||||||
existing !== incoming &&
|
|
||||||
!(isArray(existing) && existing.includes(incoming))
|
|
||||||
) {
|
|
||||||
ret[key] = existing
|
|
||||||
? [].concat(existing as any, incoming as any)
|
|
||||||
: incoming
|
|
||||||
}
|
|
||||||
} else if (key !== '') {
|
|
||||||
ret[key] = toMerge[key]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,14 @@ import {
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { warn } from '../warning'
|
import { warn } from '../warning'
|
||||||
import { recordPropMetadata } from '../componentMetadata'
|
import { recordPropMetadata } from '../componentMetadata'
|
||||||
|
import { mergeInheritAttr } from './prop'
|
||||||
|
|
||||||
export function setStyle(el: HTMLElement, value: any): void {
|
export function setStyle(el: HTMLElement, value: any, root?: boolean): void {
|
||||||
const prev = recordPropMetadata(el, 'style', (value = normalizeStyle(value)))
|
const prev = recordPropMetadata(
|
||||||
|
el,
|
||||||
|
'style',
|
||||||
|
(value = normalizeStyle(root ? mergeInheritAttr('style', value) : value)),
|
||||||
|
)
|
||||||
patchStyle(el, prev, value)
|
patchStyle(el, prev, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ export { createIf } from './apiCreateIf'
|
||||||
export { createFor, createForSlots } from './apiCreateFor'
|
export { createFor, createForSlots } from './apiCreateFor'
|
||||||
export { createComponent } from './apiCreateComponent'
|
export { createComponent } from './apiCreateComponent'
|
||||||
export { createSelector } from './apiCreateSelector'
|
export { createSelector } from './apiCreateSelector'
|
||||||
|
export { setInheritAttrs } from './componentAttrs'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
resolveComponent,
|
resolveComponent,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"vue": "workspace:*"
|
"vue": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5",
|
"@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@481bcd4",
|
||||||
"vite": "catalog:",
|
"vite": "catalog:",
|
||||||
"vite-hyper-config": "^0.4.0",
|
"vite-hyper-config": "^0.4.0",
|
||||||
"vite-plugin-inspect": "^0.8.7"
|
"vite-plugin-inspect": "^0.8.7"
|
||||||
|
|
|
@ -521,8 +521,8 @@ importers:
|
||||||
version: link:../packages/vue
|
version: link:../packages/vue
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@vitejs/plugin-vue':
|
'@vitejs/plugin-vue':
|
||||||
specifier: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5
|
specifier: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4
|
||||||
version: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)
|
version: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)
|
||||||
vite:
|
vite:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||||
|
@ -1416,6 +1416,14 @@ packages:
|
||||||
vite: ^5.0.0
|
vite: ^5.0.0
|
||||||
vue: ^3.2.25
|
vue: ^3.2.25
|
||||||
|
|
||||||
|
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@481bcd4':
|
||||||
|
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4}
|
||||||
|
version: 5.1.5
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
vite: ^5.0.0
|
||||||
|
vue: ^3.2.25
|
||||||
|
|
||||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5':
|
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5':
|
||||||
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5}
|
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5}
|
||||||
version: 5.1.4
|
version: 5.1.4
|
||||||
|
@ -4495,16 +4503,16 @@ snapshots:
|
||||||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||||
vue: link:packages/vue
|
vue: link:packages/vue
|
||||||
|
|
||||||
|
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@481bcd4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)':
|
||||||
|
dependencies:
|
||||||
|
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||||
|
vue: link:packages/vue
|
||||||
|
|
||||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@3.5.12(typescript@5.6.2))':
|
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@3.5.12(typescript@5.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||||
vue: 3.5.12(typescript@5.6.2)
|
vue: 3.5.12(typescript@5.6.2)
|
||||||
|
|
||||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)':
|
|
||||||
dependencies:
|
|
||||||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
|
||||||
vue: link:packages/vue
|
|
||||||
|
|
||||||
'@vitest/coverage-v8@2.1.1(vitest@2.1.1)':
|
'@vitest/coverage-v8@2.1.1(vitest@2.1.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ampproject/remapping': 2.3.0
|
'@ampproject/remapping': 2.3.0
|
||||||
|
|
Loading…
Reference in New Issue