mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-23 12:30:33 +03:00
feat: render boolean attributes correctly (previously #317)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { booleanHtmlAttributes } from '../../shared/constants'
|
||||||
import { isUndefined } from '../../shared/typeof'
|
import { isUndefined } from '../../shared/typeof'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,7 +18,7 @@ export default function attributeGenerator({ attribute } = {}, type, data) {
|
|||||||
if (data.hasOwnProperty(attr)) {
|
if (data.hasOwnProperty(attr)) {
|
||||||
watchedAttrs.push(attr)
|
watchedAttrs.push(attr)
|
||||||
|
|
||||||
attributeStr += isUndefined(data[attr])
|
attributeStr += isUndefined(data[attr]) || booleanHtmlAttributes.includes(attr)
|
||||||
? attr
|
? attr
|
||||||
: `${attr}="${data[attr]}"`
|
: `${attr}="${data[attr]}"`
|
||||||
|
|
||||||
|
|||||||
@@ -51,3 +51,48 @@ export const tagsWithInnerContent = ['noscript', 'script', 'style']
|
|||||||
|
|
||||||
// Attributes which are inserted as childNodes instead of HTMLAttribute
|
// Attributes which are inserted as childNodes instead of HTMLAttribute
|
||||||
export const tagAttributeAsInnerContent = ['innerHTML', 'cssText']
|
export const tagAttributeAsInnerContent = ['innerHTML', 'cssText']
|
||||||
|
|
||||||
|
// from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202
|
||||||
|
export const booleanHtmlAttributes = [
|
||||||
|
'allowfullscreen',
|
||||||
|
'async',
|
||||||
|
'autofocus',
|
||||||
|
'autoplay',
|
||||||
|
'checked',
|
||||||
|
'compact',
|
||||||
|
'controls',
|
||||||
|
'declare',
|
||||||
|
'default',
|
||||||
|
'defaultchecked',
|
||||||
|
'defaultmuted',
|
||||||
|
'defaultselected',
|
||||||
|
'defer',
|
||||||
|
'disabled',
|
||||||
|
'enabled',
|
||||||
|
'formnovalidate',
|
||||||
|
'hidden',
|
||||||
|
'indeterminate',
|
||||||
|
'inert',
|
||||||
|
'ismap',
|
||||||
|
'itemscope',
|
||||||
|
'loop',
|
||||||
|
'multiple',
|
||||||
|
'muted',
|
||||||
|
'nohref',
|
||||||
|
'noresize',
|
||||||
|
'noshade',
|
||||||
|
'novalidate',
|
||||||
|
'nowrap',
|
||||||
|
'open',
|
||||||
|
'pauseonexit',
|
||||||
|
'readonly',
|
||||||
|
'required',
|
||||||
|
'reversed',
|
||||||
|
'scoped',
|
||||||
|
'seamless',
|
||||||
|
'selected',
|
||||||
|
'sortable',
|
||||||
|
'truespeed',
|
||||||
|
'typemustmatch',
|
||||||
|
'visible'
|
||||||
|
]
|
||||||
|
|||||||
@@ -141,7 +141,13 @@ const metaInfoData = {
|
|||||||
},
|
},
|
||||||
change: {
|
change: {
|
||||||
data: [{ src: 'src', async: true, defer: true, [defaultOptions.tagIDKeyName]: 'content2' }],
|
data: [{ src: 'src', async: true, defer: true, [defaultOptions.tagIDKeyName]: 'content2' }],
|
||||||
expect: ['<script data-vue-meta="true" src="src" async="true" defer="true" data-vmid="content2"></script>']
|
expect: ['<script data-vue-meta="true" src="src" async="true" defer data-vmid="content2"></script>'],
|
||||||
|
test(side, defaultTest) {
|
||||||
|
if (side === 'client') {
|
||||||
|
// jsdom doesnt generate valid boolean attributes
|
||||||
|
this.expect[0] = this.expect[0].replace('defer', 'defer="true"')
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
remove: {
|
remove: {
|
||||||
data: [],
|
data: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user