diff --git a/.gitignore b/.gitignore index 8a3d346..183367a 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ package-lock.json lib es .vue-meta +.nuxt # examples yarn lock examples/yarn.lock diff --git a/src/client/updaters/tag.js b/src/client/updaters/tag.js index 25d5cc9..affb0fb 100644 --- a/src/client/updaters/tag.js +++ b/src/client/updaters/tag.js @@ -52,7 +52,13 @@ export default function updateTag(appId, { attribute, tagIDKeyName } = {}, type, const _attr = includes(dataAttributes, attr) ? `data-${attr}` : attr - const value = isUndefined(tag[attr]) || includes(booleanHtmlAttributes, attr) ? '' : tag[attr] + + const isBooleanAttribute = includes(booleanHtmlAttributes, attr) + if (isBooleanAttribute && !tag[attr]) { + continue + } + + const value = isBooleanAttribute ? '' : tag[attr] newElement.setAttribute(_attr, value) } } diff --git a/src/server/generators/tag.js b/src/server/generators/tag.js index 44599da..109aa54 100644 --- a/src/server/generators/tag.js +++ b/src/server/generators/tag.js @@ -36,7 +36,12 @@ export default function tagGenerator(appId, { attribute, tagIDKeyName } = {}, ty prefix = 'data-' } - return isUndefined(tag[attr]) || booleanHtmlAttributes.includes(attr) + const isBooleanAttr = booleanHtmlAttributes.includes(attr) + if (isBooleanAttr && !tag[attr]) { + return attrsStr + } + + return isBooleanAttr ? `${attrsStr} ${prefix}${attr}` : `${attrsStr} ${prefix}${attr}="${tag[attr]}"` }, '') diff --git a/test/unit/escaping.test.js b/test/unit/escaping.test.js index f9c26f0..3906e33 100644 --- a/test/unit/escaping.test.js +++ b/test/unit/escaping.test.js @@ -71,4 +71,35 @@ describe('escaping', () => { __dangerouslyDisableSanitizersByTagID: { noscape: ['innerHTML'] } }) }) + + test.skip('special chars are escaped unless disabled by vmid', () => { + const component = new Vue({ + metaInfo: { + title: 'Hello', + script: [ + { vmid: 'yescape', innerHTML: ['12', 'asd'] } + ] + } + }) + + expect(getMetaInfo(component, [[/&/g, '&']])).toEqual({ + title: 'Hello', + titleChunk: 'Hello', + titleTemplate: '%s', + htmlAttrs: {}, + headAttrs: {}, + bodyAttrs: {}, + meta: [], + base: [], + link: [], + style: [], + script: [ + { innerHTML: 'Hello & Goodbye', vmid: 'yescape' }, + { innerHTML: 'Hello & Goodbye', vmid: 'noscape' } + ], + noscript: [], + __dangerouslyDisableSanitizers: [], + __dangerouslyDisableSanitizersByTagID: { noscape: ['innerHTML'] } + }) + }) }) diff --git a/test/utils/meta-info-data.js b/test/utils/meta-info-data.js index 7314b38..1e2e1ec 100644 --- a/test/utils/meta-info-data.js +++ b/test/utils/meta-info-data.js @@ -113,12 +113,12 @@ const metaInfoData = { script: { add: { data: [ - { src: 'src', async: true, defer: true, [defaultOptions.tagIDKeyName]: 'content' }, - { src: 'src', async: true, defer: true, body: true } + { src: 'src', async: false, defer: true, [defaultOptions.tagIDKeyName]: 'content' }, + { src: 'src', async: false, defer: true, body: true } ], expect: [ - '', - '' + '', + '' ], test(side, defaultTest) { return () => {