mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-22 09:10:34 +03:00
feat: add es build
fix: add global window detection chore: update deps
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { isUndefined } from '../shared/typeof'
|
||||
import { hasGlobalWindow } from '../shared/window'
|
||||
|
||||
// fallback to timers if rAF not present
|
||||
const stopUpdate = (!isUndefined(window) ? window.cancelAnimationFrame : null) || clearTimeout
|
||||
const startUpdate = (!isUndefined(window) ? window.requestAnimationFrame : null) || (cb => setTimeout(cb, 0))
|
||||
const stopUpdate = (hasGlobalWindow ? window.cancelAnimationFrame : null) || clearTimeout
|
||||
const startUpdate = (hasGlobalWindow ? window.requestAnimationFrame : null) || (cb => setTimeout(cb, 0))
|
||||
|
||||
/**
|
||||
* Performs a batched update. Uses requestAnimationFrame to prevent
|
||||
|
||||
@@ -3,6 +3,14 @@ import { isFunction } from '../shared/typeof'
|
||||
import updateClientMetaInfo from './updateClientMetaInfo'
|
||||
|
||||
export default function _refresh(options = {}) {
|
||||
const escapeSequences = [
|
||||
[/&/g, '\u0026'],
|
||||
[/</g, '\u003c'],
|
||||
[/>/g, '\u003e'],
|
||||
[/"/g, '\u0022'],
|
||||
[/'/g, '\u0027']
|
||||
]
|
||||
|
||||
/**
|
||||
* When called, will update the current meta info with new meta info.
|
||||
* Useful when updating meta info as the result of an asynchronous
|
||||
@@ -14,7 +22,7 @@ export default function _refresh(options = {}) {
|
||||
* @return {Object} - new meta info
|
||||
*/
|
||||
return function refresh() {
|
||||
const metaInfo = getMetaInfo(options, this.$root)
|
||||
const metaInfo = getMetaInfo(options, this.$root, escapeSequences)
|
||||
|
||||
const tags = updateClientMetaInfo(options, metaInfo)
|
||||
// emit "event" with new info
|
||||
|
||||
@@ -3,6 +3,14 @@ import { metaInfoOptionKeys } from '../shared/constants'
|
||||
import generateServerInjector from './generateServerInjector'
|
||||
|
||||
export default function _inject(options = {}) {
|
||||
const escapeSequences = [
|
||||
[/&/g, '&'],
|
||||
[/</g, '<'],
|
||||
[/>/g, '>'],
|
||||
[/"/g, '"'],
|
||||
[/'/g, ''']
|
||||
]
|
||||
|
||||
/**
|
||||
* Converts the state of the meta info object such that each item
|
||||
* can be compiled to a tag string on the server
|
||||
@@ -10,10 +18,9 @@ export default function _inject(options = {}) {
|
||||
* @this {Object} - Vue instance - ideally the root component
|
||||
* @return {Object} - server meta info with `toString` methods
|
||||
*/
|
||||
|
||||
return function inject() {
|
||||
// get meta info with sensible defaults
|
||||
const metaInfo = getMetaInfo(options, this.$root)
|
||||
const metaInfo = getMetaInfo(options, this.$root, escapeSequences)
|
||||
|
||||
// generate server injectors
|
||||
for (const key in metaInfo) {
|
||||
|
||||
@@ -1,25 +1,9 @@
|
||||
import deepmerge from 'deepmerge'
|
||||
import isPlainObject from 'lodash.isplainobject'
|
||||
import { isUndefined, isFunction, isString } from '../shared/typeof'
|
||||
import { isFunction, isString } from './typeof'
|
||||
import isArray from './isArray'
|
||||
import getComponentOption from './getComponentOption'
|
||||
|
||||
const escapeHTML = str => isUndefined(window)
|
||||
// server-side escape sequence
|
||||
? String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
// client-side escape sequence
|
||||
: String(str)
|
||||
.replace(/&/g, '\u0026')
|
||||
.replace(/</g, '\u003c')
|
||||
.replace(/>/g, '\u003e')
|
||||
.replace(/"/g, '\u0022')
|
||||
.replace(/'/g, '\u0027')
|
||||
|
||||
const applyTemplate = (component, template, chunk) =>
|
||||
isFunction(template) ? template.call(component, chunk) : template.replace(/%s/g, chunk)
|
||||
|
||||
@@ -30,7 +14,7 @@ const applyTemplate = (component, template, chunk) =>
|
||||
* @param {Object} component - the Vue instance to get meta info from
|
||||
* @return {Object} - returned meta info
|
||||
*/
|
||||
export default function getMetaInfo({ keyName, tagIDKeyName, metaTemplateKeyName, contentKeyName } = {}, component) {
|
||||
export default function getMetaInfo({ keyName, tagIDKeyName, metaTemplateKeyName, contentKeyName } = {}, component, escapeSequences = []) {
|
||||
// set some sane defaults
|
||||
const defaultInfo = {
|
||||
title: '',
|
||||
@@ -139,7 +123,7 @@ export default function getMetaInfo({ keyName, tagIDKeyName, metaTemplateKeyName
|
||||
|
||||
if (!isDisabled) {
|
||||
if (isString(val)) {
|
||||
escaped[key] = escapeHTML(val)
|
||||
escaped[key] = escapeSequences.reduce((val, [v, r]) => val.replace(v, r), val)
|
||||
} else if (isPlainObject(val)) {
|
||||
escaped[key] = escape(val)
|
||||
} else if (isArray(val)) {
|
||||
|
||||
+8
-55
@@ -1,6 +1,6 @@
|
||||
import triggerUpdate from '../client/triggerUpdate'
|
||||
import { isUndefined, isFunction } from '../shared/typeof'
|
||||
import { ensuredPush } from '../shared/ensure'
|
||||
import { isUndefined, isFunction } from './typeof'
|
||||
import { ensuredPush } from './ensure'
|
||||
|
||||
export default function createMixin(options) {
|
||||
// for which Vue lifecycle hooks should the metaInfo be refreshed
|
||||
@@ -35,10 +35,6 @@ export default function createMixin(options) {
|
||||
}
|
||||
}
|
||||
|
||||
updateOnLifecycleHook.forEach((lifecycleHook) => {
|
||||
ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook))
|
||||
})
|
||||
|
||||
// force an initial refresh on page load and prevent other lifecycleHooks
|
||||
// to triggerUpdate until this initial refresh is finished
|
||||
// this is to make sure that when a page is opened in an inactive tab which
|
||||
@@ -49,6 +45,7 @@ export default function createMixin(options) {
|
||||
if (!this.$root._vueMetaInitialized) {
|
||||
ensuredPush(this.$options, 'mounted', () => {
|
||||
if (!this.$root._vueMetaInitialized) {
|
||||
// refresh meta in nextTick so all child components have loaded
|
||||
this.$nextTick(function () {
|
||||
this.$root.$meta().refresh()
|
||||
this.$root._vueMetaInitialized = true
|
||||
@@ -60,6 +57,11 @@ export default function createMixin(options) {
|
||||
|
||||
// do not trigger refresh on the server side
|
||||
if (!this.$isServer) {
|
||||
// no need to add this hooks on server side, there we only need the mounted hook above
|
||||
updateOnLifecycleHook.forEach((lifecycleHook) => {
|
||||
ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook))
|
||||
})
|
||||
|
||||
// re-render meta data when returning from a child component to parent
|
||||
ensuredPush(this.$options, 'destroyed', () => {
|
||||
// Wait that element is hidden before refreshing meta tags (to support animations)
|
||||
@@ -80,54 +82,5 @@ export default function createMixin(options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Not yet removed
|
||||
created() {
|
||||
// if computed $metaInfo exists, watch it for updates & trigger a refresh
|
||||
// when it changes (i.e. automatically handle async actions that affect metaInfo)
|
||||
// credit for this suggestion goes to [Sébastien Chopin](https://github.com/Atinux)
|
||||
if (!this.$isServer && this.$metaInfo) {
|
||||
this.$watch('$metaInfo', () => triggerUpdate(this))
|
||||
}
|
||||
|
||||
},
|
||||
activated() {
|
||||
if (this._hasMetaInfo) {
|
||||
triggerUpdate(this)
|
||||
}
|
||||
},
|
||||
deactivated() {
|
||||
if (this._hasMetaInfo) {
|
||||
triggerUpdate(this)
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
if (this._hasMetaInfo) {
|
||||
triggerUpdate(this)
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
// do not trigger refresh on the server side
|
||||
if (this.$isServer) {
|
||||
return
|
||||
}
|
||||
|
||||
// re-render meta data when returning from a child component to parent
|
||||
if (this._hasMetaInfo) {
|
||||
// Wait that element is hidden before refreshing meta tags (to support animations)
|
||||
const interval = setInterval(() => {
|
||||
if (this.$el && this.$el.offsetParent !== null) {
|
||||
return
|
||||
}
|
||||
|
||||
clearInterval(interval)
|
||||
|
||||
if (!this.$parent) {
|
||||
return
|
||||
}
|
||||
|
||||
triggerUpdate(this)
|
||||
}, 50)
|
||||
}
|
||||
}/**/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
export function isUndefined(arg) {
|
||||
return typeof arg === 'undefined'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user