From: Evan You Date: Mon, 9 Aug 2021 18:39:40 +0000 (-0400) Subject: fix(compiler-dom): stringify eligible svg content X-Git-Tag: v3.2.0~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2641422aa7b438513dd6eab357e39028c5876e52;p=thirdparty%2Fvuejs%2Fcore.git fix(compiler-dom): stringify eligible svg content fix #4282 --- diff --git a/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts b/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts index b9e7d81208..0923f0816c 100644 --- a/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts +++ b/packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts @@ -360,4 +360,28 @@ describe('stringify static html', () => { ] }) }) + + test('should stringify svg', () => { + const svg = `` + const repeated = `` + const { ast } = compileWithStringify( + `
${svg}${repeat( + repeated, + StringifyThresholds.ELEMENT_WITH_BINDING_COUNT + )}
` + ) + expect(ast.hoists[0]).toMatchObject({ + type: NodeTypes.JS_CALL_EXPRESSION, + callee: CREATE_STATIC, + arguments: [ + JSON.stringify( + `${svg}${repeat( + repeated, + StringifyThresholds.ELEMENT_WITH_BINDING_COUNT + )}` + ), + '1' + ] + }) + }) }) diff --git a/packages/compiler-dom/src/transforms/stringifyStatic.ts b/packages/compiler-dom/src/transforms/stringifyStatic.ts index c3e8d9419b..ac818ed839 100644 --- a/packages/compiler-dom/src/transforms/stringifyStatic.ts +++ b/packages/compiler-dom/src/transforms/stringifyStatic.ts @@ -20,14 +20,16 @@ import { isVoidTag, isString, isSymbol, - isKnownAttr, + isKnownHtmlAttr, escapeHtml, toDisplayString, normalizeClass, normalizeStyle, stringifyStyle, - makeMap + makeMap, + isKnownSvgAttr } from '@vue/shared' +import { DOMNamespaces } from '../parserOptions' export const enum StringifyThresholds { ELEMENT_WITH_BINDING_COUNT = 5, @@ -138,8 +140,14 @@ const getHoistedNode = (node: TemplateChildNode) => node.codegenNode.hoisted const dataAriaRE = /^(data|aria)-/ -const isStringifiableAttr = (name: string) => { - return isKnownAttr(name) || dataAriaRE.test(name) +const isStringifiableAttr = (name: string, ns: DOMNamespaces) => { + return ( + (ns === DOMNamespaces.HTML + ? isKnownHtmlAttr(name) + : ns === DOMNamespaces.SVG + ? isKnownSvgAttr(name) + : false) || dataAriaRE.test(name) + ) } const replaceHoist = ( @@ -175,6 +183,7 @@ function analyzeNode(node: StringifiableNode): [number, number] | false { let ec = node.props.length > 0 ? 1 : 0 // element w/ binding count let bailed = false const bail = (): false => { + debugger bailed = true return false } @@ -187,7 +196,10 @@ function analyzeNode(node: StringifiableNode): [number, number] | false { for (let i = 0; i < node.props.length; i++) { const p = node.props[i] // bail on non-attr bindings - if (p.type === NodeTypes.ATTRIBUTE && !isStringifiableAttr(p.name)) { + if ( + p.type === NodeTypes.ATTRIBUTE && + !isStringifiableAttr(p.name, node.ns) + ) { return bail() } if (p.type === NodeTypes.DIRECTIVE && p.name === 'bind') { @@ -195,7 +207,7 @@ function analyzeNode(node: StringifiableNode): [number, number] | false { if ( p.arg && (p.arg.type === NodeTypes.COMPOUND_EXPRESSION || - (p.arg.isStatic && !isStringifiableAttr(p.arg.content))) + (p.arg.isStatic && !isStringifiableAttr(p.arg.content, node.ns))) ) { return bail() } diff --git a/packages/shared/src/domAttrConfig.ts b/packages/shared/src/domAttrConfig.ts index 689533dd92..93f1b36d32 100644 --- a/packages/shared/src/domAttrConfig.ts +++ b/packages/shared/src/domAttrConfig.ts @@ -66,7 +66,7 @@ export const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap( * Don't also forget to allow `data-*` and `aria-*`! * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes */ -export const isKnownAttr = /*#__PURE__*/ makeMap( +export const isKnownHtmlAttr = /*#__PURE__*/ makeMap( `accept,accept-charset,accesskey,action,align,allow,alt,async,` + `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` + `border,buffered,capture,challenge,charset,checked,cite,class,code,` + @@ -83,3 +83,48 @@ export const isKnownAttr = /*#__PURE__*/ makeMap( `start,step,style,summary,tabindex,target,title,translate,type,usemap,` + `value,width,wrap` ) + +/** + * Generated from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute + */ +export const isKnownSvgAttr = /*#__PURE__*/ makeMap( + `xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,` + + `arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,` + + `baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,` + + `clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,` + + `color-interpolation-filters,color-profile,color-rendering,` + + `contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,` + + `descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,` + + `dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,` + + `fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,` + + `font-family,font-size,font-size-adjust,font-stretch,font-style,` + + `font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,` + + `glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,` + + `gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,` + + `horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,` + + `k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,` + + `lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,` + + `marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,` + + `mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,` + + `name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,` + + `overflow,overline-position,overline-thickness,panose-1,paint-order,path,` + + `pathLength,patternContentUnits,patternTransform,patternUnits,ping,` + + `pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,` + + `preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,` + + `rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,` + + `restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,` + + `specularConstant,specularExponent,speed,spreadMethod,startOffset,` + + `stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,` + + `strikethrough-position,strikethrough-thickness,string,stroke,` + + `stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,` + + `stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,` + + `systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,` + + `text-decoration,text-rendering,textLength,to,transform,transform-origin,` + + `type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,` + + `unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,` + + `v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,` + + `vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,` + + `writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,` + + `xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,` + + `xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan` +)