]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(ssr): adjust helper structure + renderList
authorEvan You <yyx990803@gmail.com>
Mon, 3 Feb 2020 23:16:09 +0000 (18:16 -0500)
committerEvan You <yyx990803@gmail.com>
Mon, 3 Feb 2020 23:31:11 +0000 (18:31 -0500)
packages/compiler-ssr/src/runtimeHelpers.ts
packages/server-renderer/__tests__/interpolate.spec.ts
packages/server-renderer/__tests__/renderList.spec.ts [new file with mode: 0644]
packages/server-renderer/__tests__/renderProps.spec.ts
packages/server-renderer/src/helpers/interpolate.ts [new file with mode: 0644]
packages/server-renderer/src/helpers/renderAttrs.ts [moved from packages/server-renderer/src/renderProps.ts with 71% similarity]
packages/server-renderer/src/helpers/renderList.ts [new file with mode: 0644]
packages/server-renderer/src/index.ts
packages/server-renderer/src/renderToString.ts

index 1d5609974a7b104efab70c5ae941f44f72e615fb..b986ce7f2bb4ef1a71fdb1ed6d08531038810d50 100644 (file)
@@ -5,7 +5,8 @@ export const SSR_RENDER_COMPONENT = Symbol(`renderComponent`)
 export const SSR_RENDER_SLOT = Symbol(`renderSlot`)
 export const SSR_RENDER_CLASS = Symbol(`renderClass`)
 export const SSR_RENDER_STYLE = Symbol(`renderStyle`)
-export const SSR_RENDER_PROPS = Symbol(`renderProps`)
+export const SSR_RENDER_ATTRS = Symbol(`renderAttrs`)
+export const SSR_RENDER_ATTR = Symbol(`renderAttr`)
 export const SSR_RENDER_LIST = Symbol(`renderList`)
 
 // Note: these are helpers imported from @vue/server-renderer
@@ -16,6 +17,7 @@ registerRuntimeHelpers({
   [SSR_RENDER_SLOT]: `_renderSlot`,
   [SSR_RENDER_CLASS]: `_renderClass`,
   [SSR_RENDER_STYLE]: `_renderStyle`,
-  [SSR_RENDER_PROPS]: `_renderProps`,
+  [SSR_RENDER_ATTRS]: `renderAttrs`,
+  [SSR_RENDER_ATTR]: `renderAttr`,
   [SSR_RENDER_LIST]: `_renderList`
 })
index a9c8fb34457a81cef26ae5ac70d71a5fb2e2d4f7..c3a5ae41e431159a3a2fa0c041a446d6caf47a54 100644 (file)
@@ -1,16 +1,16 @@
-import { _interpolate } from '../src'
+import { interpolate } from '../src/helpers/interpolate'
 import { escapeHtml } from '@vue/shared'
 
 test('ssr: interpolate', () => {
-  expect(_interpolate(0)).toBe(`0`)
-  expect(_interpolate(`foo`)).toBe(`foo`)
-  expect(_interpolate(`<div>`)).toBe(`&lt;div&gt;`)
+  expect(interpolate(0)).toBe(`0`)
+  expect(interpolate(`foo`)).toBe(`foo`)
+  expect(interpolate(`<div>`)).toBe(`&lt;div&gt;`)
   // should escape interpolated values
-  expect(_interpolate([1, 2, 3])).toBe(
+  expect(interpolate([1, 2, 3])).toBe(
     escapeHtml(JSON.stringify([1, 2, 3], null, 2))
   )
   expect(
-    _interpolate({
+    interpolate({
       foo: 1,
       bar: `<div>`
     })
diff --git a/packages/server-renderer/__tests__/renderList.spec.ts b/packages/server-renderer/__tests__/renderList.spec.ts
new file mode 100644 (file)
index 0000000..700f5eb
--- /dev/null
@@ -0,0 +1,3 @@
+test('ssr: renderList', () => {
+  // TODO
+})
index 6df970c6174ccc6dd687cf4f5610be25a3d46254..de95884857dc9d2a3d0551f3558253228444ff79 100644 (file)
@@ -1,9 +1,13 @@
-import { renderProps, renderClass, renderStyle } from '../src/renderProps'
+import {
+  renderAttrs,
+  renderClass,
+  renderStyle
+} from '../src/helpers/renderAttrs'
 
 describe('ssr: renderProps', () => {
   test('ignore reserved props', () => {
     expect(
-      renderProps({
+      renderAttrs({
         key: 1,
         ref: () => {},
         onClick: () => {}
@@ -13,7 +17,7 @@ describe('ssr: renderProps', () => {
 
   test('normal attrs', () => {
     expect(
-      renderProps({
+      renderAttrs({
         id: 'foo',
         title: 'bar'
       })
@@ -22,7 +26,7 @@ describe('ssr: renderProps', () => {
 
   test('escape attrs', () => {
     expect(
-      renderProps({
+      renderAttrs({
         id: '"><script'
       })
     ).toBe(` id="&quot;&gt;&lt;script"`)
@@ -30,7 +34,7 @@ describe('ssr: renderProps', () => {
 
   test('boolean attrs', () => {
     expect(
-      renderProps({
+      renderAttrs({
         checked: true,
         multiple: false
       })
@@ -39,7 +43,7 @@ describe('ssr: renderProps', () => {
 
   test('ignore falsy values', () => {
     expect(
-      renderProps({
+      renderAttrs({
         foo: false,
         title: null,
         baz: undefined
@@ -49,7 +53,7 @@ describe('ssr: renderProps', () => {
 
   test('props to attrs', () => {
     expect(
-      renderProps({
+      renderAttrs({
         readOnly: true, // simple lower case conversion
         htmlFor: 'foobar' // special cases
       })
@@ -58,7 +62,7 @@ describe('ssr: renderProps', () => {
 
   test('preserve name on custom element', () => {
     expect(
-      renderProps(
+      renderAttrs(
         {
           fooBar: 'ok'
         },
@@ -71,7 +75,7 @@ describe('ssr: renderProps', () => {
 describe('ssr: renderClass', () => {
   test('via renderProps', () => {
     expect(
-      renderProps({
+      renderAttrs({
         class: ['foo', 'bar']
       })
     ).toBe(` class="foo bar"`)
@@ -92,7 +96,7 @@ describe('ssr: renderClass', () => {
 describe('ssr: renderStyle', () => {
   test('via renderProps', () => {
     expect(
-      renderProps({
+      renderAttrs({
         style: {
           color: 'red'
         }
diff --git a/packages/server-renderer/src/helpers/interpolate.ts b/packages/server-renderer/src/helpers/interpolate.ts
new file mode 100644 (file)
index 0000000..17d8c35
--- /dev/null
@@ -0,0 +1,5 @@
+import { escapeHtml, toDisplayString } from '@vue/shared'
+
+export function interpolate(value: unknown): string {
+  return escapeHtml(toDisplayString(value))
+}
similarity index 71%
rename from packages/server-renderer/src/renderProps.ts
rename to packages/server-renderer/src/helpers/renderAttrs.ts
index 4830aca3529b9751c89dcb861f1656fe76583e55..4549903cb1a393698844cd92e21d7b52f978dd04 100644 (file)
@@ -14,7 +14,7 @@ import {
 
 const shouldIgnoreProp = makeMap(`key,ref,innerHTML,textContent`)
 
-export function renderProps(
+export function renderAttrs(
   props: Record<string, unknown>,
   tag?: string
 ): string {
@@ -32,23 +32,30 @@ export function renderProps(
       ret += ` class="${renderClass(value)}"`
     } else if (key === 'style') {
       ret += ` style="${renderStyle(value)}"`
-    } else if (value != null) {
-      const attrKey =
-        tag && tag.indexOf('-') > 0
-          ? key // preserve raw name on custom elements
-          : propsToAttrMap[key] || key.toLowerCase()
-      if (isBooleanAttr(attrKey)) {
-        if (value !== false) {
-          ret += ` ${attrKey}`
-        }
-      } else if (isSSRSafeAttrName(attrKey)) {
-        ret += ` ${attrKey}="${escapeHtml(value)}"`
-      }
+    } else {
+      ret += renderAttr(key, value, tag)
     }
   }
   return ret
 }
 
+export function renderAttr(key: string, value: unknown, tag?: string): string {
+  if (value == null) {
+    return ``
+  }
+  const attrKey =
+    tag && tag.indexOf('-') > 0
+      ? key // preserve raw name on custom elements
+      : propsToAttrMap[key] || key.toLowerCase()
+  if (isBooleanAttr(attrKey)) {
+    return value === false ? `` : ` ${attrKey}`
+  } else if (isSSRSafeAttrName(attrKey)) {
+    return ` ${attrKey}="${escapeHtml(value)}"`
+  } else {
+    return ``
+  }
+}
+
 export function renderClass(raw: unknown): string {
   return escapeHtml(normalizeClass(raw))
 }
diff --git a/packages/server-renderer/src/helpers/renderList.ts b/packages/server-renderer/src/helpers/renderList.ts
new file mode 100644 (file)
index 0000000..8b4a0c7
--- /dev/null
@@ -0,0 +1,29 @@
+import { isArray, isString, isObject } from '@vue/shared'
+
+export function renderList(
+  source: unknown,
+  renderItem: (value: unknown, key: string | number, index?: number) => void
+) {
+  if (isArray(source) || isString(source)) {
+    for (let i = 0, l = source.length; i < l; i++) {
+      renderItem(source[i], i)
+    }
+  } else if (typeof source === 'number') {
+    for (let i = 0; i < source; i++) {
+      renderItem(i + 1, i)
+    }
+  } else if (isObject(source)) {
+    if (source[Symbol.iterator as any]) {
+      const arr = Array.from(source as Iterable<any>)
+      for (let i = 0, l = arr.length; i < l; i++) {
+        renderItem(arr[i], i)
+      }
+    } else {
+      const keys = Object.keys(source)
+      for (let i = 0, l = keys.length; i < l; i++) {
+        const key = keys[i]
+        renderItem(source[key], key, i)
+      }
+    }
+  }
+}
index defb3af77fe0141ab53ca477914b1d5b3d2379ca..cec208316ceeaa2c7563cebd3621265057513ee7 100644 (file)
@@ -1,7 +1,7 @@
 // public
 export { renderToString } from './renderToString'
 
-// internal
+// internal runtime helpers
 export {
   renderComponent as _renderComponent,
   renderSlot as _renderSlot
@@ -9,12 +9,7 @@ export {
 export {
   renderClass as _renderClass,
   renderStyle as _renderStyle,
-  renderProps as _renderProps
-} from './renderProps'
-
-// utils
-import { escapeHtml, toDisplayString } from '@vue/shared'
-
-export function _interpolate(value: unknown): string {
-  return escapeHtml(toDisplayString(value))
-}
+  renderAttrs as _renderAttrs
+} from './helpers/renderAttrs'
+export { interpolate as _interpolate } from './helpers/interpolate'
+export { renderList as _renderList } from './helpers/renderList'
index b649e4db784fc2de7c0910cd29bb639de0c08fb0..3d0f01244b16c9570c135688544a58e970a62bf5 100644 (file)
@@ -19,10 +19,10 @@ import {
   isPromise,
   isArray,
   isFunction,
-  isVoidTag
+  isVoidTag,
+  escapeHtml
 } from '@vue/shared'
-import { renderProps } from './renderProps'
-import { escapeHtml } from '@vue/shared'
+import { renderAttrs } from './helpers/renderAttrs'
 
 const {
   isVNode,
@@ -213,7 +213,7 @@ function renderElement(
   // TODO directives
 
   if (props !== null) {
-    openTag += renderProps(props, tag)
+    openTag += renderAttrs(props, tag)
   }
 
   if (scopeId !== null) {