feat(compiler-dom): transform for v-html
This commit is contained in:
@@ -68,6 +68,8 @@ export const enum ErrorCodes {
|
||||
X_FOR_MALFORMED_EXPRESSION,
|
||||
X_V_BIND_NO_EXPRESSION,
|
||||
X_V_ON_NO_EXPRESSION,
|
||||
X_V_HTML_NO_EXPRESSION,
|
||||
X_V_HTML_WITH_CHILDREN,
|
||||
X_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET,
|
||||
X_NAMED_SLOT_ON_COMPONENT,
|
||||
X_MIXED_SLOT_USAGE,
|
||||
@@ -144,6 +146,8 @@ export const errorMessages: { [code: number]: string } = {
|
||||
[ErrorCodes.X_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
|
||||
[ErrorCodes.X_V_BIND_NO_EXPRESSION]: `v-bind is missing expression.`,
|
||||
[ErrorCodes.X_V_ON_NO_EXPRESSION]: `v-on is missing expression.`,
|
||||
[ErrorCodes.X_V_HTML_NO_EXPRESSION]: `v-html is missing epxression.`,
|
||||
[ErrorCodes.X_V_HTML_WITH_CHILDREN]: `v-html will override element children.`,
|
||||
[ErrorCodes.X_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET]: `Unexpected custom directive on <slot> outlet.`,
|
||||
[ErrorCodes.X_NAMED_SLOT_ON_COMPONENT]:
|
||||
`Named v-slot on component. ` +
|
||||
|
||||
@@ -78,7 +78,8 @@ export {
|
||||
TransformOptions,
|
||||
TransformContext,
|
||||
NodeTransform,
|
||||
StructuralDirectiveTransform
|
||||
StructuralDirectiveTransform,
|
||||
DirectiveTransform
|
||||
} from './transform'
|
||||
export {
|
||||
generate,
|
||||
|
||||
@@ -45,6 +45,7 @@ export type NodeTransform = (
|
||||
// It translates the raw directive into actual props for the VNode.
|
||||
export type DirectiveTransform = (
|
||||
dir: DirectiveNode,
|
||||
node: ElementNode,
|
||||
context: TransformContext
|
||||
) => {
|
||||
props: Property | Property[]
|
||||
|
||||
@@ -13,8 +13,7 @@ import {
|
||||
createObjectProperty,
|
||||
createSimpleExpression,
|
||||
createObjectExpression,
|
||||
Property,
|
||||
SourceLocation
|
||||
Property
|
||||
} from '../ast'
|
||||
import { isArray, PatchFlags, PatchFlagNames } from '@vue/shared'
|
||||
import { createCompilerError, ErrorCodes } from '../errors'
|
||||
@@ -44,7 +43,6 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
return () => {
|
||||
const isComponent = node.tagType === ElementTypes.COMPONENT
|
||||
let hasProps = node.props.length > 0
|
||||
const hasChildren = node.children.length > 0
|
||||
let patchFlag: number = 0
|
||||
let runtimeDirectives: DirectiveNode[] | undefined
|
||||
let dynamicPropNames: string[] | undefined
|
||||
@@ -59,12 +57,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
]
|
||||
// props
|
||||
if (hasProps) {
|
||||
const propsBuildResult = buildProps(
|
||||
node.props,
|
||||
node.loc,
|
||||
context,
|
||||
isComponent
|
||||
)
|
||||
const propsBuildResult = buildProps(node, context)
|
||||
patchFlag = propsBuildResult.patchFlag
|
||||
dynamicPropNames = propsBuildResult.dynamicPropNames
|
||||
runtimeDirectives = propsBuildResult.directives
|
||||
@@ -75,6 +68,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
}
|
||||
}
|
||||
// children
|
||||
const hasChildren = node.children.length > 0
|
||||
if (hasChildren) {
|
||||
if (!hasProps) {
|
||||
args.push(`null`)
|
||||
@@ -162,16 +156,17 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
export type PropsExpression = ObjectExpression | CallExpression | ExpressionNode
|
||||
|
||||
export function buildProps(
|
||||
props: ElementNode['props'],
|
||||
elementLoc: SourceLocation,
|
||||
node: ElementNode,
|
||||
context: TransformContext,
|
||||
isComponent: boolean = false
|
||||
props: ElementNode['props'] = node.props
|
||||
): {
|
||||
props: PropsExpression | undefined
|
||||
directives: DirectiveNode[]
|
||||
patchFlag: number
|
||||
dynamicPropNames: string[]
|
||||
} {
|
||||
const elementLoc = node.loc
|
||||
const isComponent = node.tagType === ElementTypes.COMPONENT
|
||||
let properties: ObjectExpression['properties'] = []
|
||||
const mergeArgs: PropsExpression[] = []
|
||||
const runtimeDirectives: DirectiveNode[] = []
|
||||
@@ -278,7 +273,7 @@ export function buildProps(
|
||||
const directiveTransform = context.directiveTransforms[name]
|
||||
if (directiveTransform) {
|
||||
// has built-in directive transform.
|
||||
const { props, needRuntime } = directiveTransform(prop, context)
|
||||
const { props, needRuntime } = directiveTransform(prop, node, context)
|
||||
if (isArray(props)) {
|
||||
properties.push(...props)
|
||||
properties.forEach(analyzePatchFlag)
|
||||
|
||||
@@ -52,9 +52,9 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
|
||||
let hasProps = propsWithoutName.length > 0
|
||||
if (hasProps) {
|
||||
const { props: propsExpression, directives } = buildProps(
|
||||
propsWithoutName,
|
||||
loc,
|
||||
context
|
||||
node,
|
||||
context,
|
||||
propsWithoutName
|
||||
)
|
||||
if (directives.length) {
|
||||
context.onError(
|
||||
|
||||
@@ -7,7 +7,7 @@ import { CAMELIZE } from '../runtimeHelpers'
|
||||
// v-bind without arg is handled directly in ./element.ts due to it affecting
|
||||
// codegen for the entire props object. This transform here is only for v-bind
|
||||
// *with* args.
|
||||
export const transformBind: DirectiveTransform = (dir, context) => {
|
||||
export const transformBind: DirectiveTransform = (dir, node, context) => {
|
||||
const { exp, modifiers, loc } = dir
|
||||
const arg = dir.arg!
|
||||
if (!exp) {
|
||||
|
||||
@@ -17,7 +17,7 @@ const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]
|
||||
// v-on without arg is handled directly in ./element.ts due to it affecting
|
||||
// codegen for the entire props object. This transform here is only for v-on
|
||||
// *with* args.
|
||||
export const transformOn: DirectiveTransform = (dir, context) => {
|
||||
export const transformOn: DirectiveTransform = (dir, node, context) => {
|
||||
const { loc, modifiers } = dir
|
||||
const arg = dir.arg!
|
||||
if (!dir.exp && !modifiers.length) {
|
||||
|
||||
Reference in New Issue
Block a user