]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip(compiler-ssr): v-html, v-text & textarea value
authorEvan You <yyx990803@gmail.com>
Mon, 3 Feb 2020 16:46:14 +0000 (11:46 -0500)
committerEvan You <yyx990803@gmail.com>
Mon, 3 Feb 2020 23:31:10 +0000 (18:31 -0500)
packages/compiler-ssr/__tests__/ssrCompile.spec.ts [deleted file]
packages/compiler-ssr/__tests__/ssrElement.spec.ts [new file with mode: 0644]
packages/compiler-ssr/__tests__/ssrText.spec.ts [new file with mode: 0644]
packages/compiler-ssr/__tests__/utils.ts [new file with mode: 0644]
packages/compiler-ssr/src/runtimeHelpers.ts
packages/compiler-ssr/src/transforms/ssrTransformElement.ts

diff --git a/packages/compiler-ssr/__tests__/ssrCompile.spec.ts b/packages/compiler-ssr/__tests__/ssrCompile.spec.ts
deleted file mode 100644 (file)
index ab9013a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-import { compile } from '../src'
-
-function getString(src: string): string {
-  return compile(src).code.match(/_push\((.*)\)/)![1]
-}
-
-describe('element', () => {
-  test('basic elements', () => {
-    expect(getString(`<div></div>`)).toMatchInlineSnapshot(`"\`<div></div>\`"`)
-    expect(getString(`<div/>`)).toMatchInlineSnapshot(`"\`<div></div>\`"`)
-  })
-
-  test('static attrs', () => {
-    expect(getString(`<div id="foo" class="bar"></div>`)).toMatchInlineSnapshot(
-      `"\`<div id=\\"foo\\" class=\\"bar\\"></div>\`"`
-    )
-  })
-
-  test('nested elements', () => {
-    expect(
-      getString(`<div><span></span><span></span></div>`)
-    ).toMatchInlineSnapshot(`"\`<div><span></span><span></span></div>\`"`)
-  })
-
-  test('void element', () => {
-    expect(getString(`<input>`)).toMatchInlineSnapshot(`"\`<input>\`"`)
-  })
-})
-
-describe('text', () => {
-  test('static text', () => {
-    expect(getString(`foo`)).toMatchInlineSnapshot(`"\`foo\`"`)
-  })
-
-  test('static text escape', () => {
-    expect(getString(`&lt;foo&gt;`)).toMatchInlineSnapshot(`"\`&lt;foo&gt;\`"`)
-  })
-
-  test('nested elements with static text', () => {
-    expect(
-      getString(`<div><span>hello</span><span>bye</span></div>`)
-    ).toMatchInlineSnapshot(
-      `"\`<div><span>hello</span><span>bye</span></div>\`"`
-    )
-  })
-
-  test('interpolation', () => {
-    expect(getString(`foo {{ bar }} baz`)).toMatchInlineSnapshot(
-      `"\`foo \${interpolate(_ctx.bar)} baz\`"`
-    )
-  })
-
-  test('nested elements with interpolation', () => {
-    expect(
-      getString(
-        `<div><span>{{ foo }} bar</span><span>baz {{ qux }}</span></div>`
-      )
-    ).toMatchInlineSnapshot(
-      `"\`<div><span>\${interpolate(_ctx.foo)} bar</span><span>baz \${interpolate(_ctx.qux)}</span></div>\`"`
-    )
-  })
-})
diff --git a/packages/compiler-ssr/__tests__/ssrElement.spec.ts b/packages/compiler-ssr/__tests__/ssrElement.spec.ts
new file mode 100644 (file)
index 0000000..c4c9add
--- /dev/null
@@ -0,0 +1,52 @@
+import { getCompiledString } from './utils'
+
+describe('element', () => {
+  test('basic elements', () => {
+    expect(getCompiledString(`<div></div>`)).toMatchInlineSnapshot(
+      `"\`<div></div>\`"`
+    )
+    expect(getCompiledString(`<div/>`)).toMatchInlineSnapshot(
+      `"\`<div></div>\`"`
+    )
+  })
+
+  test('static attrs', () => {
+    expect(
+      getCompiledString(`<div id="foo" class="bar"></div>`)
+    ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\" class=\\"bar\\"></div>\`"`)
+  })
+
+  test('nested elements', () => {
+    expect(
+      getCompiledString(`<div><span></span><span></span></div>`)
+    ).toMatchInlineSnapshot(`"\`<div><span></span><span></span></div>\`"`)
+  })
+
+  test('void element', () => {
+    expect(getCompiledString(`<input>`)).toMatchInlineSnapshot(`"\`<input>\`"`)
+  })
+
+  test('v-html', () => {
+    expect(getCompiledString(`<div v-html="foo"/>`)).toMatchInlineSnapshot(
+      `"\`<div>\${_ctx.foo}</div>\`"`
+    )
+  })
+
+  test('v-text', () => {
+    expect(getCompiledString(`<div v-text="foo"/>`)).toMatchInlineSnapshot(
+      `"\`<div>\${interpolate(_ctx.foo)}</div>\`"`
+    )
+  })
+
+  test('<textarea> with dynamic value', () => {
+    expect(getCompiledString(`<textarea :value="foo"/>`)).toMatchInlineSnapshot(
+      `"\`<textarea>\${interpolate(_ctx.foo)}</textarea>\`"`
+    )
+  })
+
+  test('<textarea> with static value', () => {
+    expect(
+      getCompiledString(`<textarea value="fo&gt;o"/>`)
+    ).toMatchInlineSnapshot(`"\`<textarea>fo&gt;o</textarea>\`"`)
+  })
+})
diff --git a/packages/compiler-ssr/__tests__/ssrText.spec.ts b/packages/compiler-ssr/__tests__/ssrText.spec.ts
new file mode 100644 (file)
index 0000000..9f0bb22
--- /dev/null
@@ -0,0 +1,37 @@
+import { getCompiledString } from './utils'
+
+describe('text', () => {
+  test('static text', () => {
+    expect(getCompiledString(`foo`)).toMatchInlineSnapshot(`"\`foo\`"`)
+  })
+
+  test('static text escape', () => {
+    expect(getCompiledString(`&lt;foo&gt;`)).toMatchInlineSnapshot(
+      `"\`&lt;foo&gt;\`"`
+    )
+  })
+
+  test('nested elements with static text', () => {
+    expect(
+      getCompiledString(`<div><span>hello</span><span>bye</span></div>`)
+    ).toMatchInlineSnapshot(
+      `"\`<div><span>hello</span><span>bye</span></div>\`"`
+    )
+  })
+
+  test('interpolation', () => {
+    expect(getCompiledString(`foo {{ bar }} baz`)).toMatchInlineSnapshot(
+      `"\`foo \${interpolate(_ctx.bar)} baz\`"`
+    )
+  })
+
+  test('nested elements with interpolation', () => {
+    expect(
+      getCompiledString(
+        `<div><span>{{ foo }} bar</span><span>baz {{ qux }}</span></div>`
+      )
+    ).toMatchInlineSnapshot(
+      `"\`<div><span>\${interpolate(_ctx.foo)} bar</span><span>baz \${interpolate(_ctx.qux)}</span></div>\`"`
+    )
+  })
+})
diff --git a/packages/compiler-ssr/__tests__/utils.ts b/packages/compiler-ssr/__tests__/utils.ts
new file mode 100644 (file)
index 0000000..333b1e1
--- /dev/null
@@ -0,0 +1,5 @@
+import { compile } from '../src'
+
+export function getCompiledString(src: string): string {
+  return compile(src).code.match(/_push\((.*)\)/)![1]
+}
index 3af2ec552cb8382d88d1f7f3639c7042c19a6781..5a327dd176c683a66e601df5ebc620d01a475e70 100644 (file)
@@ -1,4 +1,4 @@
-import { registerRuntimeHelpers } from '@vue/compiler-core'
+import { registerRuntimeHelpers } from '@vue/compiler-dom'
 
 export const INTERPOLATE = Symbol(`interpolate`)
 
index 89b514d9570ac739817b4e3014dda81fcfc34890..bb3e0200a43d4502501e905c590ed1aa3829ceb5 100644 (file)
@@ -3,7 +3,8 @@ import {
   NodeTypes,
   ElementTypes,
   TemplateLiteral,
-  createTemplateLiteral
+  createTemplateLiteral,
+  createInterpolation
 } from '@vue/compiler-dom'
 import { escapeHtml } from '@vue/shared'
 
@@ -43,27 +44,57 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
       // element
       // generate the template literal representing the open tag.
       const openTag: TemplateLiteral['elements'] = [`<${node.tag}`]
+      let rawChildren
 
       for (let i = 0; i < node.props.length; i++) {
         const prop = node.props[i]
         if (prop.type === NodeTypes.DIRECTIVE) {
-          const directiveTransform = context.directiveTransforms[prop.name]
-          if (directiveTransform) {
-            // TODO directive transforms
+          // special cases with children override
+          if (prop.name === 'html' && prop.exp) {
+            node.children = []
+            rawChildren = prop.exp
+          } else if (prop.name === 'text' && prop.exp) {
+            node.children = [createInterpolation(prop.exp, prop.loc)]
+          } else if (
+            // v-bind:value on textarea
+            node.tag === 'textarea' &&
+            prop.name === 'bind' &&
+            prop.exp &&
+            prop.arg &&
+            prop.arg.type === NodeTypes.SIMPLE_EXPRESSION &&
+            prop.arg.isStatic &&
+            prop.arg.content === 'value'
+          ) {
+            node.children = [createInterpolation(prop.exp, prop.loc)]
+            // TODO handle <textrea> with dynamic v-bind
           } else {
-            // no corresponding ssr directive transform found.
-            // TODO emit error
+            const directiveTransform = context.directiveTransforms[prop.name]
+            if (directiveTransform) {
+              // TODO directive transforms
+            } else {
+              // no corresponding ssr directive transform found.
+              // TODO emit error
+            }
           }
         } else {
-          // static prop
-          openTag.push(
-            ` ${prop.name}` +
-              (prop.value ? `="${escapeHtml(prop.value.content)}"` : ``)
-          )
+          // special case: value on <textarea>
+          if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
+            node.children = []
+            rawChildren = escapeHtml(prop.value.content)
+          } else {
+            // static prop
+            openTag.push(
+              ` ${prop.name}` +
+                (prop.value ? `="${escapeHtml(prop.value.content)}"` : ``)
+            )
+          }
         }
       }
 
       openTag.push(`>`)
+      if (rawChildren) {
+        openTag.push(rawChildren)
+      }
       node.ssrCodegenNode = createTemplateLiteral(openTag)
     }
   }