2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-22 12:30:33 +03:00

feat: support generating tags directly from metaInfo object

This commit is contained in:
pimlie
2019-07-28 16:13:58 +02:00
committed by Pim
parent 931c0c4e88
commit cb2758eb0f
17 changed files with 128 additions and 70 deletions
+7 -2
View File
@@ -1,6 +1,7 @@
import { clientSequences } from '../shared/escaping'
import { getComponentMetaInfo } from '../shared/getComponentOption'
import getMetaInfo from '../shared/getMetaInfo'
import { isFunction } from '../utils/is-type'
import { clientSequences } from '../shared/escaping'
import updateClientMetaInfo from './updateClientMetaInfo'
export default function _refresh (options = {}) {
@@ -15,10 +16,14 @@ export default function _refresh (options = {}) {
* @return {Object} - new meta info
*/
return function refresh () {
const metaInfo = getMetaInfo(options, this.$root, clientSequences)
// collect & aggregate all metaInfo $options
const rawInfo = getComponentMetaInfo(options, this.$root)
const metaInfo = getMetaInfo(options, rawInfo, clientSequences, this.$root)
const appId = this.$root._vueMeta.appId
const tags = updateClientMetaInfo(appId, options, metaInfo)
// emit "event" with new info
if (tags && isFunction(metaInfo.changed)) {
metaInfo.changed(metaInfo, tags.addedTags, tags.removedTags)
+3 -1
View File
@@ -2,6 +2,7 @@ import { version } from '../package.json'
import createMixin from './shared/mixin'
import { setOptions } from './shared/options'
import $meta from './server/$meta'
import generate from './server/generate'
import { hasMetaInfo } from './shared/meta-helpers'
/**
@@ -24,5 +25,6 @@ function install (Vue, options = {}) {
export default {
version,
install,
hasMetaInfo
hasMetaInfo,
generate
}
+15
View File
@@ -0,0 +1,15 @@
import getMetaInfo from '../shared/getMetaInfo'
import { defaultOptions } from '../shared/constants'
import { serverSequences } from '../shared/escaping'
import { setOptions } from '../shared/options'
import generateServerInjector from './generateServerInjector'
export default function generate (options, rawInfo) {
if (arguments.length === 1) {
rawInfo = options
options = defaultOptions
}
const metaInfo = getMetaInfo(setOptions(options), rawInfo, serverSequences)
return generateServerInjector(options, metaInfo)
}
+19 -9
View File
@@ -1,4 +1,4 @@
import { metaInfoAttributeKeys } from '../shared/constants'
import { metaInfoOptionKeys, metaInfoAttributeKeys, defaultInfo } from '../shared/constants'
import { titleGenerator, attributeGenerator, tagGenerator } from './generators'
/**
@@ -9,14 +9,24 @@ import { titleGenerator, attributeGenerator, tagGenerator } from './generators'
* @return {Object} - the new injector
*/
export default function generateServerInjector (options, type, data) {
if (type === 'title') {
return titleGenerator(options, type, data)
export default function generateServerInjector (options, newInfo) {
for (const type in defaultInfo) {
if (metaInfoOptionKeys.includes(type)) {
continue
}
if (type === 'title') {
newInfo[type] = titleGenerator(options, type, newInfo[type])
continue
}
if (metaInfoAttributeKeys.includes(type)) {
newInfo[type] = attributeGenerator(options, type, newInfo[type])
continue
}
newInfo[type] = tagGenerator(options, type, newInfo[type])
}
if (metaInfoAttributeKeys.includes(type)) {
return attributeGenerator(options, type, data)
}
return tagGenerator(options, type, data)
return newInfo
}
+4
View File
@@ -18,6 +18,10 @@ export default function tagGenerator ({ ssrAppId, attribute, tagIDKeyName } = {}
return {
text ({ body = false, pbody = false } = {}) {
if (!tags || !tags.length) {
return ''
}
// build a string containing all tags of this type
return tags.reduce((tagsStr, tag) => {
if (tag.skip) {
+7 -9
View File
@@ -1,6 +1,6 @@
import getMetaInfo from '../shared/getMetaInfo'
import { metaInfoOptionKeys } from '../shared/constants'
import { serverSequences } from '../shared/escaping'
import { getComponentMetaInfo } from '../shared/getComponentOption'
import getMetaInfo from '../shared/getMetaInfo'
import generateServerInjector from './generateServerInjector'
export default function _inject (options = {}) {
@@ -12,15 +12,13 @@ export default function _inject (options = {}) {
* @return {Object} - server meta info with `toString` methods
*/
return function inject () {
// get meta info with sensible defaults
const metaInfo = getMetaInfo(options, this.$root, serverSequences)
// collect & aggregate all metaInfo $options
const rawInfo = getComponentMetaInfo(options, this.$root)
const metaInfo = getMetaInfo(options, rawInfo, serverSequences, this.$root)
// generate server injectors
for (const key in metaInfo) {
if (!metaInfoOptionKeys.includes(key) && metaInfo.hasOwnProperty(key)) {
metaInfo[key] = generateServerInjector(options, key, metaInfo[key])
}
}
generateServerInjector(options, metaInfo)
return metaInfo
}
+22
View File
@@ -1,5 +1,6 @@
import { isString, isArray, isPureObject } from '../utils/is-type'
import { includes } from '../utils/array'
import { ensureIsArray } from '../utils/ensure'
import { metaInfoOptionKeys, disableOptionKeys } from './constants'
export const serverSequences = [
@@ -78,3 +79,24 @@ export function escape (info, options, escapeOptions, escapeKeys) {
return escaped
}
export function escapeMetaInfo (options, info, escapeSequences = []) {
const escapeOptions = {
doEscape: value => escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value)
}
disableOptionKeys.forEach((disableKey, index) => {
if (index === 0) {
ensureIsArray(info, disableKey)
} else if (index === 1) {
for (const key in info[disableKey]) {
ensureIsArray(info[disableKey], key)
}
}
escapeOptions[disableKey] = info[disableKey]
})
// begin sanitization
return escape(info, options, escapeOptions)
}
+6 -1
View File
@@ -1,9 +1,14 @@
import { isFunction, isObject } from '../utils/is-type'
import { findIndex } from '../utils/array'
import { defaultInfo } from './constants'
import { merge } from './merge'
import { applyTemplate } from './template'
import { inMetaInfoBranch } from './meta-helpers'
export function getComponentMetaInfo (options = {}, component) {
return getComponentOption(options, component, defaultInfo)
}
/**
* Returns the `opts.option` $option value of the given `opts.component`.
* If methods are encountered, they will be bound to the component context.
@@ -18,7 +23,7 @@ import { inMetaInfoBranch } from './meta-helpers'
* @param {Object} [result={}] - result so far
* @return {Object} result - final aggregated result
*/
export default function getComponentOption (options = {}, component, result = {}) {
export function getComponentOption (options = {}, component, result = {}) {
const { keyName, metaTemplateKeyName, tagIDKeyName } = options
const { $options, $children } = component
+3 -28
View File
@@ -1,8 +1,5 @@
import { ensureIsArray } from '../utils/ensure'
import { escapeMetaInfo } from '../shared/escaping'
import { applyTemplate } from './template'
import { defaultInfo, disableOptionKeys } from './constants'
import { escape } from './escaping'
import getComponentOption from './getComponentOption'
/**
* Returns the correct meta info for the given component
@@ -11,10 +8,7 @@ import getComponentOption from './getComponentOption'
* @param {Object} component - the Vue instance to get meta info from
* @return {Object} - returned meta info
*/
export default function getMetaInfo (options = {}, component, escapeSequences = []) {
// collect & aggregate all metaInfo $options
let info = getComponentOption(options, component, defaultInfo)
export default function getMetaInfo (options = {}, info, escapeSequences = [], component) {
// Remove all "template" tags from meta
// backup the title chunk in case user wants access to it
@@ -33,24 +27,5 @@ export default function getMetaInfo (options = {}, component, escapeSequences =
info.base = Object.keys(info.base).length ? [info.base] : []
}
const escapeOptions = {
doEscape: value => escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value)
}
disableOptionKeys.forEach((disableKey, index) => {
if (index === 0) {
ensureIsArray(info, disableKey)
} else if (index === 1) {
for (const key in info[disableKey]) {
ensureIsArray(info[disableKey], key)
}
}
escapeOptions[disableKey] = info[disableKey]
})
// begin sanitization
info = escape(info, options, escapeOptions)
return info
return escapeMetaInfo(options, info, escapeSequences)
}