diff --git a/src/server/generators/title.js b/src/server/generators/title.js index 3c11690..5f15272 100644 --- a/src/server/generators/title.js +++ b/src/server/generators/title.js @@ -8,6 +8,9 @@ export default function titleGenerator (appId, { attribute } = {}, type, data) { return { text () { + if (!data) { + return '' + } return `<${type}>${data}` } } diff --git a/src/shared/escaping.js b/src/shared/escaping.js index b9873b3..8f9b123 100644 --- a/src/shared/escaping.js +++ b/src/shared/escaping.js @@ -1,4 +1,4 @@ -import { isString, isArray, isObject } from '../utils/is-type' +import { isString, isArray, isPureObject } from '../utils/is-type' import { includes } from '../utils/array' import { metaInfoOptionKeys, disableOptionKeys } from './constants' @@ -55,11 +55,11 @@ export function escape (info, options, escapeOptions) { escaped[key] = doEscape(value) } else if (isArray(value)) { escaped[key] = value.map((v) => { - return isObject(v) + return isPureObject(v) ? escape(v, options, escapeOptions) : doEscape(v) }) - } else if (isObject(value)) { + } else if (isPureObject(value)) { escaped[key] = escape(value, options, escapeOptions) } else { escaped[key] = value diff --git a/src/utils/is-type.js b/src/utils/is-type.js index 31ce5ea..51dbf13 100644 --- a/src/utils/is-type.js +++ b/src/utils/is-type.js @@ -15,6 +15,10 @@ export function isObject (arg) { return typeof arg === 'object' } +export function isPureObject (arg) { + return typeof arg === 'object' && arg !== null +} + export function isFunction (arg) { return typeof arg === 'function' } diff --git a/test/unit/escaping.test.js b/test/unit/escaping.test.js index 3906e33..29e5ab0 100644 --- a/test/unit/escaping.test.js +++ b/test/unit/escaping.test.js @@ -39,6 +39,31 @@ describe('escaping', () => { }) }) + test('null title is left as it is', () => { + const component = new Vue({ + metaInfo: { + title: null + } + }) + + expect(getMetaInfo(component, [[/&/g, '&']])).toEqual({ + title: null, + titleChunk: '', + titleTemplate: '%s', + htmlAttrs: {}, + headAttrs: {}, + bodyAttrs: {}, + meta: [], + base: [], + link: [], + style: [], + script: [], + noscript: [], + __dangerouslyDisableSanitizers: [], + __dangerouslyDisableSanitizersByTagID: {} + }) + }) + test('special chars are escaped unless disabled by vmid', () => { const component = new Vue({ metaInfo: { diff --git a/test/unit/generators.test.js b/test/unit/generators.test.js index f1a50f8..a078f6b 100644 --- a/test/unit/generators.test.js +++ b/test/unit/generators.test.js @@ -1,6 +1,7 @@ import _generateServerInjector from '../../src/server/generateServerInjector' import { defaultOptions } from '../../src/shared/constants' import metaInfoData from '../utils/meta-info-data' +import { titleGenerator } from '../../src/server/generators' const generateServerInjector = (type, data) => _generateServerInjector('test', defaultOptions, type, data) @@ -59,3 +60,10 @@ describe('generators', () => { }) }) }) + +describe('title generator should return an empty string when title is null', () => { + const title = null + const generatedTitle = titleGenerator(0, {}, 'title', title) + + expect(generatedTitle.text()).toEqual('') +})