2
0
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:
pimlie
2019-02-20 17:05:51 +01:00
parent 1e47a37d6e
commit 56f0b61d1b
11 changed files with 165 additions and 91 deletions
+3 -3
View File
@@ -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
+9 -1
View File
@@ -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
+9 -2
View File
@@ -3,6 +3,14 @@ import { metaInfoOptionKeys } from '../shared/constants'
import generateServerInjector from './generateServerInjector'
export default function _inject(options = {}) {
const escapeSequences = [
[/&/g, '&amp;'],
[/</g, '&lt;'],
[/>/g, '&gt;'],
[/"/g, '&quot;'],
[/'/g, '&#x27;']
]
/**
* 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) {
+3 -19
View File
@@ -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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;')
// 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
View File
@@ -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
View File
@@ -1,4 +1,3 @@
export function isUndefined(arg) {
return typeof arg === 'undefined'
}