From 04b2692f0b9b7e43ed5e04648b622995c7593e55 Mon Sep 17 00:00:00 2001 From: pimlie Date: Fri, 26 Jul 2019 15:45:13 +0000 Subject: [PATCH] chore(release): 2.1.1 --- CHANGELOG.md | 31 + dist/vue-meta.common.js | 1095 +++++++++++++--------- dist/vue-meta.esm.browser.js | 1470 +++++++++++++++++------------- dist/vue-meta.esm.browser.min.js | 2 +- dist/vue-meta.esm.js | 1095 +++++++++++++--------- dist/vue-meta.js | 992 ++++++++++++-------- dist/vue-meta.min.js | 2 +- package.json | 2 +- 8 files changed, 2874 insertions(+), 1815 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e288c9..d6e0bde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [2.1.1](https://github.com/nuxt/vue-meta/compare/v2.0.3...v2.1.1) (2019-07-26) + + +### Bug Fixes + +* add warning for v1 boolean attribute syntax ([bfeab17](https://github.com/nuxt/vue-meta/commit/bfeab17)) +* also use ssrAppId for client update ([50c0509](https://github.com/nuxt/vue-meta/commit/50c0509)) +* babel config for rollup ([71b2d52](https://github.com/nuxt/vue-meta/commit/71b2d52)) +* don't generate tag if metaInfo.title is null or false ([#409](https://github.com/nuxt/vue-meta/issues/409)) ([39ef287](https://github.com/nuxt/vue-meta/commit/39ef287)) +* dont change title when value is undefined (fix [#396](https://github.com/nuxt/vue-meta/issues/396)) ([90f9710](https://github.com/nuxt/vue-meta/commit/90f9710)) +* dont update title on client with falsy value except empty string ([6efcdf1](https://github.com/nuxt/vue-meta/commit/6efcdf1)) +* ensure hasAttribute exists on $root.$el ([f1511ac](https://github.com/nuxt/vue-meta/commit/f1511ac)) +* only show boolean attrs with truthy value ([1d9072a](https://github.com/nuxt/vue-meta/commit/1d9072a)) + + +### Features + +* add option for prepending (no)script to body ([#410](https://github.com/nuxt/vue-meta/issues/410)) ([05163a7](https://github.com/nuxt/vue-meta/commit/05163a7)) +* auto add ssrAttribute to htmlAttrs ([9cf6d32](https://github.com/nuxt/vue-meta/commit/9cf6d32)) +* enable onload callbacks ([#414](https://github.com/nuxt/vue-meta/issues/414)) ([fc71e1f](https://github.com/nuxt/vue-meta/commit/fc71e1f)) +* make ssr app id configurable ([b0c85e5](https://github.com/nuxt/vue-meta/commit/b0c85e5)) +* support json content (without disabling sanitizers) ([#415](https://github.com/nuxt/vue-meta/issues/415)) ([51fe6ea](https://github.com/nuxt/vue-meta/commit/51fe6ea)) + + +### Tests + +* enable all getMetaInfo tests again ([24d7fee](https://github.com/nuxt/vue-meta/commit/24d7fee)) +* update browser config ([8c35863](https://github.com/nuxt/vue-meta/commit/8c35863)) + + + ## [2.1.0](https://github.com/nuxt/vue-meta/compare/v2.0.3...v2.1.0) (2019-07-24) diff --git a/dist/vue-meta.common.js b/dist/vue-meta.common.js index f92adca..03d5e07 100644 --- a/dist/vue-meta.common.js +++ b/dist/vue-meta.common.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.1.0 + * vue-meta v2.1.1 * (c) 2019 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -13,10 +13,10 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau var deepmerge = _interopDefault(require('deepmerge')); -var version = "2.1.0"; +var version = "2.1.1"; // store an id to keep track of DOM updates -let batchId = null; +var batchId = null; function triggerUpdate(vm, hookName) { // if an update was triggered during initialization or when an update was triggered by the // metaInfo watcher, set initialized to null @@ -27,7 +27,9 @@ function triggerUpdate(vm, hookName) { if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) { // batch potential DOM updates to prevent extraneous re-rendering - batchUpdate(() => vm.$meta().refresh()); + batchUpdate(function () { + return vm.$meta().refresh(); + }); } } /** @@ -38,14 +40,136 @@ function triggerUpdate(vm, hookName) { * @return {Number} id - a new ID */ -function batchUpdate(callback, timeout = 10) { +function batchUpdate(callback) { + var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; clearTimeout(batchId); - batchId = setTimeout(() => { + batchId = setTimeout(function () { callback(); }, timeout); return batchId; } +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + keys.push.apply(keys, symbols); + } + + return keys; +} + +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(source, true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(source).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; +} + +function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); +} + /** * checks if passed argument is an array * @param {any} arg - the object to check @@ -58,10 +182,10 @@ function isUndefined(arg) { return typeof arg === 'undefined'; } function isObject(arg) { - return typeof arg === 'object'; + return _typeof(arg) === 'object'; } function isPureObject(arg) { - return typeof arg === 'object' && arg !== null; + return _typeof(arg) === 'object' && arg !== null; } function isFunction(arg) { return typeof arg === 'function'; @@ -86,11 +210,13 @@ function ensuredPush(object, key, el) { object[key].push(el); } -function hasMetaInfo(vm = this) { +function hasMetaInfo() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; return vm && (vm._vueMeta === true || isObject(vm._vueMeta)); } // a component is in a metaInfo branch when itself has meta info or one of its (grand-)children has -function inMetaInfoBranch(vm = this) { +function inMetaInfoBranch() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; return vm && !isUndefined(vm._vueMeta); } @@ -102,16 +228,15 @@ function addNavGuards(vm) { } vm.$root._vueMeta.navGuards = true; - const $router = vm.$root.$router; - const $meta = vm.$root.$meta(); - $router.beforeEach((to, from, next) => { + var $router = vm.$root.$router; + var $meta = vm.$root.$meta(); + $router.beforeEach(function (to, from, next) { $meta.pause(); next(); }); - $router.afterEach(() => { - const { - metaInfo - } = $meta.resume(); + $router.afterEach(function () { + var _$meta$resume = $meta.resume(), + metaInfo = _$meta$resume.metaInfo; if (metaInfo && metaInfo.afterNavigation && isFunction(metaInfo.afterNavigation)) { metaInfo.afterNavigation(metaInfo); @@ -126,31 +251,32 @@ function hasGlobalWindowFn() { return false; } } -const hasGlobalWindow = hasGlobalWindowFn(); +var hasGlobalWindow = hasGlobalWindowFn(); -const _global = hasGlobalWindow ? window : global; +var _global = hasGlobalWindow ? window : global; -const console = _global.console = _global.console || {}; -function warn(...args) { +var console = _global.console = _global.console || {}; +function warn() { /* istanbul ignore next */ if (!console || !console.warn) { return; } - console.warn(...args); + console.warn.apply(console, arguments); } -let appId = 1; +var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates return { - beforeCreate() { + beforeCreate: function beforeCreate() { + var _this = this; + Object.defineProperty(this, '_hasMetaInfo', { configurable: true, - - get() { + get: function get() { // Show deprecation warning once when devtools enabled if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) { warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead'); @@ -159,7 +285,6 @@ function createMixin(Vue, options) { return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo // _vnode is used to know that it's attached to a real component // useful if we use some mixin to add some meta tags (like nuxt-i18n) @@ -167,7 +292,7 @@ function createMixin(Vue, options) { if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) { if (!this.$root._vueMeta) { this.$root._vueMeta = { - appId + appId: appId }; appId++; } // to speed up updates we keep track of branches which have a component with vue-meta info defined @@ -176,7 +301,7 @@ function createMixin(Vue, options) { if (!this._vueMeta) { this._vueMeta = true; - let p = this.$parent; + var p = this.$parent; while (p && p !== this.$root) { if (isUndefined(p._vueMeta)) { @@ -200,8 +325,8 @@ function createMixin(Vue, options) { // 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) - ensuredPush(this.$options, 'created', () => { - this.$watch('$metaInfo', function () { + ensuredPush(this.$options, 'created', function () { + _this.$watch('$metaInfo', function () { triggerUpdate(this, 'watcher'); }); }); @@ -216,33 +341,37 @@ function createMixin(Vue, options) { this.$root._vueMeta.initialized = this.$isServer; if (!this.$root._vueMeta.initialized) { - ensuredPush(this.$options, 'beforeMount', () => { + ensuredPush(this.$options, 'beforeMount', function () { // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if (this.$root.$el && this.$root.$el.hasAttribute && this.$root.$el.hasAttribute('data-server-rendered')) { - this.$root._vueMeta.appId = options.ssrAppId; + if (_this.$root.$el && _this.$root.$el.hasAttribute && _this.$root.$el.hasAttribute('data-server-rendered')) { + _this.$root._vueMeta.appId = options.ssrAppId; } }); // we use the mounted hook here as on page load - ensuredPush(this.$options, 'mounted', () => { - if (!this.$root._vueMeta.initialized) { + ensuredPush(this.$options, 'mounted', function () { + if (!_this.$root._vueMeta.initialized) { // used in triggerUpdate to check if a change was triggered // during initialization - this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded + _this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded - this.$nextTick(function () { - const { - tags, - metaInfo - } = this.$root.$meta().refresh(); // After ssr hydration (identifier by tags === false) check + _this.$nextTick(function () { + var _this2 = this; + + var _this$$root$$meta$ref = this.$root.$meta().refresh(), + tags = _this$$root$$meta$ref.tags, + metaInfo = _this$$root$$meta$ref.metaInfo; // After ssr hydration (identifier by tags === false) check // if initialized was set to null in triggerUpdate. That'd mean // that during initilazation changes where triggered which need // to be applied OR a metaInfo watcher was triggered before the // current hook was called // (during initialization all changes are blocked) + if (tags === false && this.$root._vueMeta.initialized === null) { - this.$nextTick(() => triggerUpdate(this, 'initializing')); + this.$nextTick(function () { + return triggerUpdate(_this2, 'initializing'); + }); } this.$root._vueMeta.initialized = true; @@ -265,32 +394,33 @@ function createMixin(Vue, options) { if (!this.$isServer) { // no need to add this hooks on server side - updateOnLifecycleHook.forEach(lifecycleHook => { - ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook)); + updateOnLifecycleHook.forEach(function (lifecycleHook) { + ensuredPush(_this.$options, lifecycleHook, function () { + return triggerUpdate(_this, lifecycleHook); + }); }); // re-render meta data when returning from a child component to parent - ensuredPush(this.$options, 'destroyed', () => { + ensuredPush(this.$options, 'destroyed', function () { // Wait that element is hidden before refreshing meta tags (to support animations) - const interval = setInterval(() => { - if (this.$el && this.$el.offsetParent !== null) { + var interval = setInterval(function () { + if (_this.$el && _this.$el.offsetParent !== null) { /* istanbul ignore next line */ return; } clearInterval(interval); - if (!this.$parent) { + if (!_this.$parent) { /* istanbul ignore next line */ return; } - triggerUpdate(this, 'destroyed'); + triggerUpdate(_this, 'destroyed'); }, 50); }); } } } - }; } @@ -298,7 +428,7 @@ function createMixin(Vue, options) { * These are constant variables used throughout the application. */ // set some sane defaults -const defaultInfo = { +var defaultInfo = { title: undefined, titleChunk: '', titleTemplate: '%s', @@ -316,58 +446,58 @@ const defaultInfo = { // gets converted to the various meta tags & attributes for the page. }; -const keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should +var keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should // manage and which it should ignore. -const attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` +var attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` // that the server has already generated the meta tags for the initial render. -const ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) +var ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) // an item in a tag list. For example, if you have two `meta` tag list items // that both have `vmid` of "description", then vue-meta will overwrite the // shallowest one with the deepest one. -const tagIDKeyName = 'vmid'; // This is the key name for possible meta templates +var tagIDKeyName = 'vmid'; // This is the key name for possible meta templates -const metaTemplateKeyName = 'template'; // This is the key name for the content-holding property +var metaTemplateKeyName = 'template'; // This is the key name for the content-holding property -const contentKeyName = 'content'; // The id used for the ssr app +var contentKeyName = 'content'; // The id used for the ssr app -const ssrAppId = 'ssr'; -const defaultOptions = { - keyName, - attribute, - ssrAttribute, - tagIDKeyName, - contentKeyName, - metaTemplateKeyName, - ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) +var ssrAppId = 'ssr'; +var defaultOptions = { + keyName: keyName, + attribute: attribute, + ssrAttribute: ssrAttribute, + tagIDKeyName: tagIDKeyName, + contentKeyName: contentKeyName, + metaTemplateKeyName: metaTemplateKeyName, + ssrAppId: ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) }; -const metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping +var metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping -const disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags +var disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags -const metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event +var metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event -const tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) +var tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) // see: https://www.w3.org/TR/html52/document-metadata.html -const tagsWithoutEndTag = ['base', 'meta', 'link']; // HTML elements which can have inner content (shortened to our needs) +var tagsWithoutEndTag = ['base', 'meta', 'link']; // HTML elements which can have inner content (shortened to our needs) -const tagsWithInnerContent = ['noscript', 'script', 'style']; // Attributes which are inserted as childNodes instead of HTMLAttribute +var tagsWithInnerContent = ['noscript', 'script', 'style']; // Attributes which are inserted as childNodes instead of HTMLAttribute -const tagAttributeAsInnerContent = ['innerHTML', 'cssText', 'json']; // Attributes which should be added with data- prefix +var tagAttributeAsInnerContent = ['innerHTML', 'cssText', 'json']; // Attributes which should be added with data- prefix -const commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 +var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -const booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; +var booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; function setOptions(options) { // combine options options = isObject(options) ? options : {}; - for (const key in defaultOptions) { + for (var key in defaultOptions) { if (!options[key]) { options[key] = defaultOptions[key]; } @@ -376,20 +506,24 @@ function setOptions(options) { return options; } function getOptions(options) { - const optionsCopy = {}; + var optionsCopy = {}; - for (const key in options) { + for (var key in options) { optionsCopy[key] = options[key]; } return optionsCopy; } -function pause(refresh = true) { +function pause() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = true; - return () => resume(refresh); + return function () { + return resume(refresh); + }; } -function resume(refresh = true) { +function resume() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = false; if (refresh) { @@ -397,11 +531,11 @@ function resume(refresh = true) { } } -function applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName -}, headObject, template, chunk) { +function applyTemplate(_ref, headObject, template, chunk) { + var component = _ref.component, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; + if (isUndefined(template)) { template = headObject[metaTemplateKeyName]; delete headObject[metaTemplateKeyName]; @@ -429,62 +563,40 @@ function applyTemplate({ * files in server/ still use normal js function */ function findIndex(array, predicate) { - if ( !Array.prototype.findIndex) { - // idx needs to be a Number, for..in returns string - for (let idx = 0; idx < array.length; idx++) { - if (predicate.call(arguments[2], array[idx], idx, array)) { - return idx; - } - } - - return -1; - } return array.findIndex(predicate, arguments[2]); } function toArray(arg) { - if ( !Array.from) { - return Array.prototype.slice.call(arg); - } return Array.from(arg); } function includes(array, value) { - if ( !Array.prototype.includes) { - for (const idx in array) { - if (array[idx] === value) { - return true; - } - } - - return false; - } return array.includes(value); } -const serverSequences = [[/&/g, '&'], [/</g, '<'], [/>/g, '>'], [/"/g, '"'], [/'/g, ''']]; -const clientSequences = [[/&/g, '\u0026'], [/</g, '\u003C'], [/>/g, '\u003E'], [/"/g, '\u0022'], [/'/g, '\u0027']]; // sanitizes potentially dangerous characters +var serverSequences = [[/&/g, '&'], [/</g, '<'], [/>/g, '>'], [/"/g, '"'], [/'/g, ''']]; +var clientSequences = [[/&/g, "&"], [/</g, "<"], [/>/g, ">"], [/"/g, "\""], [/'/g, "'"]]; // sanitizes potentially dangerous characters function escape(info, options, escapeOptions) { - const { - tagIDKeyName - } = options; - const { - doEscape = v => v, - escapeKeys - } = escapeOptions; - const escaped = {}; + var tagIDKeyName = options.tagIDKeyName; + var _escapeOptions$doEsca = escapeOptions.doEscape, + doEscape = _escapeOptions$doEsca === void 0 ? function (v) { + return v; + } : _escapeOptions$doEsca, + escapeKeys = escapeOptions.escapeKeys; + var escaped = {}; - for (const key in info) { - const value = info[key]; // no need to escape configuration options + for (var key in info) { + var value = info[key]; // no need to escape configuration options if (includes(metaInfoOptionKeys, key)) { escaped[key] = value; continue; } - let [disableKey] = disableOptionKeys; + var _disableOptionKeys = _slicedToArray(disableOptionKeys, 1), + disableKey = _disableOptionKeys[0]; if (escapeOptions[disableKey] && includes(escapeOptions[disableKey], key)) { // this info[key] doesnt need to escaped if the option is listed in __dangerouslyDisableSanitizers @@ -492,7 +604,7 @@ function escape(info, options, escapeOptions) { continue; } - const tagId = info[tagIDKeyName]; + var tagId = info[tagIDKeyName]; if (tagId) { disableKey = disableOptionKeys[1]; // keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped @@ -506,25 +618,25 @@ function escape(info, options, escapeOptions) { if (isString(value)) { escaped[key] = doEscape(value); } else if (isArray(value)) { - escaped[key] = value.map(v => { + escaped[key] = value.map(function (v) { if (isPureObject(v)) { - return escape(v, options, { ...escapeOptions, + return escape(v, options, _objectSpread2({}, escapeOptions, { escapeKeys: true - }); + })); } return doEscape(v); }); } else if (isPureObject(value)) { - escaped[key] = escape(value, options, { ...escapeOptions, + escaped[key] = escape(value, options, _objectSpread2({}, escapeOptions, { escapeKeys: true - }); + })); } else { escaped[key] = value; } if (escapeKeys) { - const escapedKey = doEscape(key); + var escapedKey = doEscape(key); if (key !== escapedKey) { escaped[escapedKey] = escaped[key]; @@ -536,25 +648,26 @@ function escape(info, options, escapeOptions) { return escaped; } -function arrayMerge({ - component, - tagIDKeyName, - metaTemplateKeyName, - contentKeyName -}, target, source) { +function _arrayMerge(_ref, target, source) { + var component = _ref.component, + tagIDKeyName = _ref.tagIDKeyName, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; // we concat the arrays without merging objects contained in, // but we check for a `vmid` property on each object in the array // using an O(1) lookup associative array exploit - const destination = []; - target.forEach((targetItem, targetIndex) => { + var destination = []; + target.forEach(function (targetItem, targetIndex) { // no tagID so no need to check for duplicity if (!targetItem[tagIDKeyName]) { destination.push(targetItem); return; } - const sourceIndex = findIndex(source, item => item[tagIDKeyName] === targetItem[tagIDKeyName]); - const sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem + var sourceIndex = findIndex(source, function (item) { + return item[tagIDKeyName] === targetItem[tagIDKeyName]; + }); + var sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem if (sourceIndex === -1) { destination.push(targetItem); @@ -580,33 +693,35 @@ function arrayMerge({ } // now we only need to check if the target has a template to combine it with the source - const targetTemplate = targetItem[metaTemplateKeyName]; + var targetTemplate = targetItem[metaTemplateKeyName]; if (!targetTemplate) { return; } - const sourceTemplate = sourceItem[metaTemplateKeyName]; + var sourceTemplate = sourceItem[metaTemplateKeyName]; if (!sourceTemplate) { // use parent template and child content applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName }, sourceItem, targetTemplate); } else if (!sourceItem[contentKeyName]) { // use child template and parent content applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName }, sourceItem, undefined, targetItem[contentKeyName]); } }); return destination.concat(source); } -function merge(target, source, options = {}) { +function merge(target, source) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // remove properties explicitly set to false so child components can // optionally _not_ overwrite the parents content // (for array properties this is checked in arrayMerge) @@ -614,12 +729,12 @@ function merge(target, source, options = {}) { delete source.title; } - metaInfoAttributeKeys.forEach(attrKey => { + metaInfoAttributeKeys.forEach(function (attrKey) { if (!source[attrKey]) { return; } - for (const key in source[attrKey]) { + for (var key in source[attrKey]) { if (source[attrKey].hasOwnProperty(key) && source[attrKey][key] === undefined) { if (includes(booleanHtmlAttributes, key)) { warn('VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details'); @@ -630,7 +745,9 @@ function merge(target, source, options = {}) { } }); return deepmerge(target, source, { - arrayMerge: (t, s) => arrayMerge(options, t, s) + arrayMerge: function arrayMerge(t, s) { + return _arrayMerge(options, t, s); + } }); } @@ -649,16 +766,15 @@ function merge(target, source, options = {}) { * @return {Object} result - final aggregated result */ -function getComponentOption(options = {}, component, result = {}) { - const { - keyName, - metaTemplateKeyName, - tagIDKeyName - } = options; - const { - $options, - $children - } = component; +function getComponentOption() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var keyName = options.keyName, + metaTemplateKeyName = options.metaTemplateKeyName, + tagIDKeyName = options.tagIDKeyName; + var $options = component.$options, + $children = component.$children; if (component._inactive) { return result; @@ -666,7 +782,7 @@ function getComponentOption(options = {}, component, result = {}) { if ($options[keyName]) { - let data = $options[keyName]; // if option is a function, replace it with it's result + var data = $options[keyName]; // if option is a function, replace it with it's result if (isFunction(data)) { data = data.call(component); @@ -683,7 +799,7 @@ function getComponentOption(options = {}, component, result = {}) { if ($children.length) { - $children.forEach(childComponent => { + $children.forEach(function (childComponent) { // check if the childComponent is in a branch // return otherwise so we dont walk all component branches unnecessarily if (!inMetaInfoBranch(childComponent)) { @@ -696,12 +812,16 @@ function getComponentOption(options = {}, component, result = {}) { if (metaTemplateKeyName && result.meta) { // apply templates if needed - result.meta.forEach(metaObject => applyTemplate(options, metaObject)); // remove meta items with duplicate vmid's + result.meta.forEach(function (metaObject) { + return applyTemplate(options, metaObject); + }); // remove meta items with duplicate vmid's - result.meta = result.meta.filter((metaItem, index, arr) => { + result.meta = result.meta.filter(function (metaItem, index, arr) { return (// keep meta item if it doesnt has a vmid !metaItem.hasOwnProperty(tagIDKeyName) || // or if it's the first item in the array with this vmid - index === findIndex(arr, item => item[tagIDKeyName] === metaItem[tagIDKeyName]) + index === findIndex(arr, function (item) { + return item[tagIDKeyName] === metaItem[tagIDKeyName]; + }) ); }); } @@ -717,9 +837,12 @@ function getComponentOption(options = {}, component, result = {}) { * @return {Object} - returned meta info */ -function getMetaInfo(options = {}, component, escapeSequences = []) { +function getMetaInfo() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var escapeSequences = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; // collect & aggregate all metaInfo $options - let info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta + var info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta // backup the title chunk in case user wants access to it if (info.title) { @@ -729,7 +852,7 @@ function getMetaInfo(options = {}, component, escapeSequences = []) { if (info.titleTemplate && info.titleTemplate !== '%s') { applyTemplate({ - component, + component: component, contentKeyName: 'title' }, info, info.titleTemplate, info.titleChunk || ''); } // convert base tag to an array so it can be handled the same way @@ -740,14 +863,22 @@ 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) + var escapeOptions = { + doEscape: function doEscape(value) { + return escapeSequences.reduce(function (val, _ref) { + var _ref2 = _slicedToArray(_ref, 2), + v = _ref2[0], + r = _ref2[1]; + + return val.replace(v, r); + }, value); + } }; - disableOptionKeys.forEach((disableKey, index) => { + disableOptionKeys.forEach(function (disableKey, index) { if (index === 0) { ensureIsArray(info, disableKey); } else if (index === 1) { - for (const key in info[disableKey]) { + for (var key in info[disableKey]) { ensureIsArray(info[disableKey], key); } } @@ -766,23 +897,22 @@ function getTag(tags, tag) { return tags[tag]; } -function getElementsKey({ - body, - pbody -}) { +function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; return body ? 'body' : pbody ? 'pbody' : 'head'; } -function queryElements(parentNode, { - appId, - attribute, - type, - tagIDKeyName -}, attributes = {}) { - const queries = [`${type}[${attribute}="${appId}"]`, `${type}[data-${tagIDKeyName}]`].map(query => { - for (const key in attributes) { - const val = attributes[key]; - const attributeValue = val && val !== true ? `="${val}"` : ''; - query += `[data-${key}${attributeValue}]`; +function queryElements(parentNode, _ref2) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var queries = ["".concat(type, "[").concat(attribute, "=\"").concat(appId, "\"]"), "".concat(type, "[data-").concat(tagIDKeyName, "]")].map(function (query) { + for (var key in attributes) { + var val = attributes[key]; + var attributeValue = val && val !== true ? "=\"".concat(val, "\"") : ''; + query += "[data-".concat(key).concat(attributeValue, "]"); } return query; @@ -790,8 +920,9 @@ function queryElements(parentNode, { return toArray(parentNode.querySelectorAll(queries.join(', '))); } -const callbacks = []; -function isDOMComplete(d = document) { +var callbacks = []; +function isDOMComplete() { + var d = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; return d.readyState === 'complete'; } function addCallback(query, callback) { @@ -802,18 +933,37 @@ function addCallback(query, callback) { callbacks.push([query, callback]); } -function addCallbacks({ - tagIDKeyName -}, type, tags, autoAddListeners) { - let hasAsyncCallback = false; +function addCallbacks(_ref, type, tags, autoAddListeners) { + var tagIDKeyName = _ref.tagIDKeyName; + var hasAsyncCallback = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - for (const tag of tags) { - if (!tag[tagIDKeyName] || !tag.callback) { - continue; + try { + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var tag = _step.value; + + if (!tag[tagIDKeyName] || !tag.callback) { + continue; + } + + hasAsyncCallback = true; + addCallback("".concat(type, "[data-").concat(tagIDKeyName, "=\"").concat(tag[tagIDKeyName], "\"]"), tag.callback); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } - - hasAsyncCallback = true; - addCallback(`${type}[data-${tagIDKeyName}="${tag[tagIDKeyName]}"]`, tag.callback); } if (!autoAddListeners || !hasAsyncCallback) { @@ -831,14 +981,18 @@ function addListeners() { /* istanbul ignore next */ - document.onreadystatechange = () => { + document.onreadystatechange = function () { applyCallbacks(); }; } function applyCallbacks(matchElement) { - for (const [query, callback] of callbacks) { - const selector = `${query}[onload="this.__vm_l=1"]`; - let elements = []; + var _loop = function _loop() { + var _callbacks$_i = _slicedToArray(_callbacks[_i], 2), + query = _callbacks$_i[0], + callback = _callbacks$_i[1]; + + var selector = "".concat(query, "[onload=\"this.__vm_l=1\"]"); + var elements = []; if (!matchElement) { elements = toArray(document.querySelectorAll(selector)); @@ -848,47 +1002,78 @@ function applyCallbacks(matchElement) { elements = [matchElement]; } - for (const element of elements) { - /* __vm_cb: whether the load callback has been called - * __vm_l: set by onload attribute, whether the element was loaded - * __vm_ev: whether the event listener was added or not - */ - if (element.__vm_cb) { - continue; - } + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; - const onload = () => { - /* Mark that the callback for this element has already been called, - * this prevents the callback to run twice in some (rare) conditions + try { + var _loop2 = function _loop2() { + var element = _step2.value; + + /* __vm_cb: whether the load callback has been called + * __vm_l: set by onload attribute, whether the element was loaded + * __vm_ev: whether the event listener was added or not */ - element.__vm_cb = true; - /* onload needs to be removed because we only need the - * attribute after ssr and if we dont remove it the node - * will fail isEqualNode on the client + if (element.__vm_cb) { + return "continue"; + } + + var onload = function onload() { + /* Mark that the callback for this element has already been called, + * this prevents the callback to run twice in some (rare) conditions + */ + element.__vm_cb = true; + /* onload needs to be removed because we only need the + * attribute after ssr and if we dont remove it the node + * will fail isEqualNode on the client + */ + + element.removeAttribute('onload'); + callback(element); + }; + /* IE9 doesnt seem to load scripts synchronously, + * causing a script sometimes/often already to be loaded + * when we add the event listener below (thus adding an onload event + * listener has no use because it will never be triggered). + * Therefore we add the onload attribute during ssr, and + * check here if it was already loaded or not */ - element.removeAttribute('onload'); - callback(element); + + if (element.__vm_l) { + onload(); + return "continue"; + } + + if (!element.__vm_ev) { + element.__vm_ev = true; + element.addEventListener('load', onload); + } }; - /* IE9 doesnt seem to load scripts synchronously, - * causing a script sometimes/often already to be loaded - * when we add the event listener below (thus adding an onload event - * listener has no use because it will never be triggered). - * Therefore we add the onload attribute during ssr, and - * check here if it was already loaded or not - */ + for (var _iterator2 = elements[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var _ret = _loop2(); - if (element.__vm_l) { - onload(); - continue; + if (_ret === "continue") continue; } - - if (!element.__vm_ev) { - element.__vm_ev = true; - element.addEventListener('load', onload); + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } } } + }; + + for (var _i = 0, _callbacks = callbacks; _i < _callbacks.length; _i++) { + _loop(); } } @@ -899,17 +1084,20 @@ function applyCallbacks(matchElement) { * @param {HTMLElement} tag - the HTMLElement tag to update with new attrs */ -function updateAttribute({ - attribute -} = {}, attrs, tag) { - const vueMetaAttrString = tag.getAttribute(attribute); - const vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; - const toRemove = toArray(vueMetaAttrs); - const keepIndexes = []; +function updateAttribute() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute; - for (const attr in attrs) { + var attrs = arguments.length > 1 ? arguments[1] : undefined; + var tag = arguments.length > 2 ? arguments[2] : undefined; + var vueMetaAttrString = tag.getAttribute(attribute); + var vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; + var toRemove = toArray(vueMetaAttrs); + var keepIndexes = []; + + for (var attr in attrs) { if (attrs.hasOwnProperty(attr)) { - const value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; + var value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; tag.setAttribute(attr, value || ''); if (!includes(vueMetaAttrs, attr)) { @@ -921,7 +1109,9 @@ function updateAttribute({ } } - const removedAttributesCount = toRemove.filter((el, index) => !includes(keepIndexes, index)).reduce((acc, attr) => { + var removedAttributesCount = toRemove.filter(function (el, index) { + return !includes(keepIndexes, index); + }).reduce(function (acc, attr) { tag.removeAttribute(attr); return acc + 1; }, 0); @@ -955,20 +1145,23 @@ function updateTitle(title) { * @return {Object} - a representation of what tags changed */ -function updateTag(appId, options = {}, type, tags, head, body) { - const { - attribute, - tagIDKeyName - } = options; - const dataAttributes = [tagIDKeyName, ...commonDataAttributes]; - const newElements = []; - const queryOptions = { - appId, - attribute, - type, - tagIDKeyName +function updateTag(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var type = arguments.length > 2 ? arguments[2] : undefined; + var tags = arguments.length > 3 ? arguments[3] : undefined; + var head = arguments.length > 4 ? arguments[4] : undefined; + var body = arguments.length > 5 ? arguments[5] : undefined; + var attribute = options.attribute, + tagIDKeyName = options.tagIDKeyName; + var dataAttributes = [tagIDKeyName].concat(_toConsumableArray(commonDataAttributes)); + var newElements = []; + var queryOptions = { + appId: appId, + attribute: attribute, + type: type, + tagIDKeyName: tagIDKeyName }; - const currentElements = { + var currentElements = { head: queryElements(head, queryOptions), pbody: queryElements(body, queryOptions, { pbody: true @@ -982,109 +1175,148 @@ function updateTag(appId, options = {}, type, tags, head, body) { // remove duplicates that could have been found by merging tags // which include a mixin with metaInfo and that mixin is used // by multiple components on the same page - const found = []; - tags = tags.filter(x => { - const k = JSON.stringify(x); - const res = !includes(found, k); + var found = []; + tags = tags.filter(function (x) { + var k = JSON.stringify(x); + var res = !includes(found, k); found.push(k); return res; }); } if (tags.length) { - for (const tag of tags) { - if (tag.skip) { - continue; - } + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - const newElement = document.createElement(type); - newElement.setAttribute(attribute, appId); + try { + var _loop = function _loop() { + var tag = _step.value; - for (const attr in tag) { - /* istanbul ignore next */ - if (!tag.hasOwnProperty(attr)) { - continue; + if (tag.skip) { + return "continue"; } - if (attr === 'innerHTML') { - newElement.innerHTML = tag.innerHTML; - continue; - } + var newElement = document.createElement(type); + newElement.setAttribute(attribute, appId); - if (attr === 'json') { - newElement.innerHTML = JSON.stringify(tag.json); - continue; - } - - if (attr === 'cssText') { - if (newElement.styleSheet) { - /* istanbul ignore next */ - newElement.styleSheet.cssText = tag.cssText; - } else { - newElement.appendChild(document.createTextNode(tag.cssText)); + var _loop2 = function _loop2(attr) { + /* istanbul ignore next */ + if (!tag.hasOwnProperty(attr)) { + return "continue"; } - continue; + if (attr === 'innerHTML') { + newElement.innerHTML = tag.innerHTML; + return "continue"; + } + + if (attr === 'json') { + newElement.innerHTML = JSON.stringify(tag.json); + return "continue"; + } + + if (attr === 'cssText') { + if (newElement.styleSheet) { + /* istanbul ignore next */ + newElement.styleSheet.cssText = tag.cssText; + } else { + newElement.appendChild(document.createTextNode(tag.cssText)); + } + + return "continue"; + } + + if (attr === 'callback') { + newElement.onload = function () { + return tag[attr](newElement); + }; + + return "continue"; + } + + var _attr = includes(dataAttributes, attr) ? "data-".concat(attr) : attr; + + var isBooleanAttribute = includes(booleanHtmlAttributes, attr); + + if (isBooleanAttribute && !tag[attr]) { + return "continue"; + } + + var value = isBooleanAttribute ? '' : tag[attr]; + newElement.setAttribute(_attr, value); + }; + + for (var attr in tag) { + var _ret2 = _loop2(attr); + + if (_ret2 === "continue") continue; } - if (attr === 'callback') { - newElement.onload = () => tag[attr](newElement); + var oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - continue; + var indexToDelete = void 0; + var hasEqualElement = oldElements.some(function (existingTag, index) { + indexToDelete = index; + return newElement.isEqualNode(existingTag); + }); + + if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { + oldElements.splice(indexToDelete, 1); + } else { + newElements.push(newElement); } + }; - const _attr = includes(dataAttributes, attr) ? `data-${attr}` : attr; + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _ret = _loop(); - const isBooleanAttribute = includes(booleanHtmlAttributes, attr); - - if (isBooleanAttribute && !tag[attr]) { - continue; - } - - const value = isBooleanAttribute ? '' : tag[attr]; - newElement.setAttribute(_attr, value); + if (_ret === "continue") continue; } - - const oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - - let indexToDelete; - const hasEqualElement = oldElements.some((existingTag, index) => { - indexToDelete = index; - return newElement.isEqualNode(existingTag); - }); - - if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { - oldElements.splice(indexToDelete, 1); - } else { - newElements.push(newElement); + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } } - let oldElements = []; + var oldElements = []; - for (const current of Object.values(currentElements)) { - oldElements = [...oldElements, ...current]; + for (var _i = 0, _Object$values = Object.values(currentElements); _i < _Object$values.length; _i++) { + var current = _Object$values[_i]; + oldElements = [].concat(_toConsumableArray(oldElements), _toConsumableArray(current)); } // remove old elements - for (const element of oldElements) { + for (var _i2 = 0, _oldElements = oldElements; _i2 < _oldElements.length; _i2++) { + var element = _oldElements[_i2]; element.parentNode.removeChild(element); } // insert new elements - for (const element of newElements) { - if (element.hasAttribute('data-body')) { - body.appendChild(element); + for (var _i3 = 0, _newElements = newElements; _i3 < _newElements.length; _i3++) { + var _element = _newElements[_i3]; + + if (_element.hasAttribute('data-body')) { + body.appendChild(_element); continue; } - if (element.hasAttribute('data-pbody')) { - body.insertBefore(element, body.firstChild); + if (_element.hasAttribute('data-pbody')) { + body.insertBefore(_element, body.firstChild); continue; } - head.appendChild(element); + head.appendChild(_element); } return { @@ -1099,24 +1331,44 @@ function updateTag(appId, options = {}, type, tags, head, body) { * @param {Object} newInfo - the meta info to update to */ -function updateClientMetaInfo(appId, options = {}, newInfo) { - const { - ssrAttribute, - ssrAppId - } = options; // only cache tags for current update +function updateClientMetaInfo(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var newInfo = arguments.length > 2 ? arguments[2] : undefined; + var ssrAttribute = options.ssrAttribute, + ssrAppId = options.ssrAppId; // only cache tags for current update - const tags = {}; - const htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update + var tags = {}; + var htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update if (appId === ssrAppId && htmlTag.hasAttribute(ssrAttribute)) { // remove the server render attribute so we can update on (next) changes htmlTag.removeAttribute(ssrAttribute); // add load callbacks if the - let addLoadListeners = false; + var addLoadListeners = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - for (const type of tagsSupportingOnload) { - if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { - addLoadListeners = true; + try { + for (var _iterator = tagsSupportingOnload[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var type = _step.value; + + if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { + addLoadListeners = true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } @@ -1128,50 +1380,52 @@ function updateClientMetaInfo(appId, options = {}, newInfo) { } // initialize tracked changes - const addedTags = {}; - const removedTags = {}; + var addedTags = {}; + var removedTags = {}; - for (const type in newInfo) { + for (var _type in newInfo) { // ignore these - if (includes(metaInfoOptionKeys, type)) { + if (includes(metaInfoOptionKeys, _type)) { continue; } - if (type === 'title') { + if (_type === 'title') { // update the title updateTitle(newInfo.title); continue; } - if (includes(metaInfoAttributeKeys, type)) { - const tagName = type.substr(0, 4); - updateAttribute(options, newInfo[type], getTag(tags, tagName)); + if (includes(metaInfoAttributeKeys, _type)) { + var tagName = _type.substr(0, 4); + + updateAttribute(options, newInfo[_type], getTag(tags, tagName)); continue; } // tags should always be an array, ignore if it isnt - if (!isArray(newInfo[type])) { + if (!isArray(newInfo[_type])) { continue; } - const { - oldTags, - newTags - } = updateTag(appId, options, type, newInfo[type], getTag(tags, 'head'), getTag(tags, 'body')); + var _updateTag = updateTag(appId, options, _type, newInfo[_type], getTag(tags, 'head'), getTag(tags, 'body')), + oldTags = _updateTag.oldTags, + newTags = _updateTag.newTags; if (newTags.length) { - addedTags[type] = newTags; - removedTags[type] = oldTags; + addedTags[_type] = newTags; + removedTags[_type] = oldTags; } } return { - addedTags, - removedTags + addedTags: addedTags, + removedTags: removedTags }; } -function _refresh(options = {}) { +function _refresh() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** * When called, will update the current meta info with new meta info. * Useful when updating meta info as the result of an asynchronous @@ -1183,9 +1437,9 @@ function _refresh(options = {}) { * @return {Object} - new meta info */ return function refresh() { - const metaInfo = getMetaInfo(options, this.$root, clientSequences); - const appId = this.$root._vueMeta.appId; - const tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info + var metaInfo = getMetaInfo(options, this.$root, clientSequences); + var appId = this.$root._vueMeta.appId; + var tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info if (tags && isFunction(metaInfo.changed)) { metaInfo.changed(metaInfo, tags.addedTags, tags.removedTags); @@ -1193,8 +1447,8 @@ function _refresh(options = {}) { return { vm: this, - metaInfo, - tags + metaInfo: metaInfo, + tags: tags }; }; } @@ -1207,34 +1461,36 @@ function _refresh(options = {}) { * @return {Object} - the attribute generator */ -function attributeGenerator({ - attribute, - ssrAttribute -} = {}, type, data) { - return { - text(addSrrAttribute) { - let attributeStr = ''; - const watchedAttrs = []; +function attributeGenerator() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute, + ssrAttribute = _ref.ssrAttribute; - for (const attr in data) { + var type = arguments.length > 1 ? arguments[1] : undefined; + var data = arguments.length > 2 ? arguments[2] : undefined; + return { + text: function text(addSrrAttribute) { + var attributeStr = ''; + var watchedAttrs = []; + + for (var attr in data) { if (data.hasOwnProperty(attr)) { watchedAttrs.push(attr); - attributeStr += isUndefined(data[attr]) || booleanHtmlAttributes.includes(attr) ? attr : `${attr}="${isArray(data[attr]) ? data[attr].join(' ') : data[attr]}"`; + attributeStr += isUndefined(data[attr]) || booleanHtmlAttributes.includes(attr) ? attr : "".concat(attr, "=\"").concat(isArray(data[attr]) ? data[attr].join(' ') : data[attr], "\""); attributeStr += ' '; } } if (attributeStr) { - attributeStr += `${attribute}="${watchedAttrs.sort().join(',')}"`; + attributeStr += "".concat(attribute, "=\"").concat(watchedAttrs.sort().join(','), "\""); } if (type === 'htmlAttrs' && addSrrAttribute) { - return `${ssrAttribute}${attributeStr ? ' ' : ''}${attributeStr}`; + return "".concat(ssrAttribute).concat(attributeStr ? ' ' : '').concat(attributeStr); } return attributeStr; } - }; } @@ -1245,18 +1501,20 @@ function attributeGenerator({ * @param {String} data - the title text * @return {Object} - the title generator */ -function titleGenerator({ - attribute -} = {}, type, data) { +function titleGenerator() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute; + + var type = arguments.length > 1 ? arguments[1] : undefined; + var data = arguments.length > 2 ? arguments[2] : undefined; return { - text() { + text: function text() { if (!data) { return ''; } - return `<${type}>${data}</${type}>`; + return "<".concat(type, ">").concat(data, "</").concat(type, ">"); } - }; } @@ -1268,24 +1526,30 @@ function titleGenerator({ * @return {Object} - the tag generator */ -function tagGenerator({ - ssrAppId, - attribute, - tagIDKeyName -} = {}, type, tags) { - const dataAttributes = [tagIDKeyName, 'callback', ...commonDataAttributes]; +function tagGenerator() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + ssrAppId = _ref.ssrAppId, + attribute = _ref.attribute, + tagIDKeyName = _ref.tagIDKeyName; + + var type = arguments.length > 1 ? arguments[1] : undefined; + var tags = arguments.length > 2 ? arguments[2] : undefined; + var dataAttributes = [tagIDKeyName, 'callback'].concat(_toConsumableArray(commonDataAttributes)); return { - text({ - body = false, - pbody = false - } = {}) { + text: function text() { + var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref2$body = _ref2.body, + body = _ref2$body === void 0 ? false : _ref2$body, + _ref2$pbody = _ref2.pbody, + pbody = _ref2$pbody === void 0 ? false : _ref2$pbody; + // build a string containing all tags of this type - return tags.reduce((tagsStr, tag) => { + return tags.reduce(function (tagsStr, tag) { if (tag.skip) { return tagsStr; } - const tagKeys = Object.keys(tag); + var tagKeys = Object.keys(tag); if (tagKeys.length === 0) { return tagsStr; // Bail on empty tag object @@ -1295,53 +1559,52 @@ function tagGenerator({ return tagsStr; } - let attrs = tag.once ? '' : ` ${attribute}="${ssrAppId}"`; // build a string containing all attributes of this tag + var attrs = tag.once ? '' : " ".concat(attribute, "=\"").concat(ssrAppId, "\""); // build a string containing all attributes of this tag - for (const attr in tag) { + for (var attr in tag) { // these attributes are treated as children on the tag if (tagAttributeAsInnerContent.includes(attr) || attr === 'once') { continue; } // these form the attribute list for this tag - let prefix = ''; + var prefix = ''; if (dataAttributes.includes(attr)) { prefix = 'data-'; } if (attr === 'callback') { - attrs += ` onload="this.__vm_l=1"`; + attrs += " onload=\"this.__vm_l=1\""; continue; } - const isBooleanAttr = !prefix && booleanHtmlAttributes.includes(attr); + var isBooleanAttr = !prefix && booleanHtmlAttributes.includes(attr); if (isBooleanAttr && !tag[attr]) { continue; } - attrs += ` ${prefix}${attr}` + (isBooleanAttr ? '' : `="${tag[attr]}"`); + attrs += " ".concat(prefix).concat(attr) + (isBooleanAttr ? '' : "=\"".concat(tag[attr], "\"")); } - let json = ''; + var json = ''; if (tag.json) { json = JSON.stringify(tag.json); } // grab child content from one of these attributes, if possible - const content = tag.innerHTML || tag.cssText || json; // generate tag exactly without any other redundant attribute + var content = tag.innerHTML || tag.cssText || json; // generate tag exactly without any other redundant attribute // these tags have no end tag - const hasEndTag = !tagsWithoutEndTag.includes(type); // these tag types will have content inserted + var hasEndTag = !tagsWithoutEndTag.includes(type); // these tag types will have content inserted - const hasContent = hasEndTag && tagsWithInnerContent.includes(type); // the final string for this specific tag + var hasContent = hasEndTag && tagsWithInnerContent.includes(type); // the final string for this specific tag - return `${tagsStr}<${type}${attrs}${!hasContent && hasEndTag ? '/' : ''}>` + (hasContent ? `${content}</${type}>` : ''); + return "".concat(tagsStr, "<").concat(type).concat(attrs).concat(!hasContent && hasEndTag ? '/' : '', ">") + (hasContent ? "".concat(content, "</").concat(type, ">") : ''); }, ''); } - }; } @@ -1365,7 +1628,9 @@ function generateServerInjector(options, type, data) { return tagGenerator(options, type, data); } -function _inject(options = {}) { +function _inject() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** * Converts the state of the meta info object such that each item * can be compiled to a tag string on the server @@ -1375,9 +1640,9 @@ function _inject(options = {}) { */ return function inject() { // get meta info with sensible defaults - const metaInfo = getMetaInfo(options, this.$root, serverSequences); // generate server injectors + var metaInfo = getMetaInfo(options, this.$root, serverSequences); // generate server injectors - for (const key in metaInfo) { + for (var key in metaInfo) { if (!metaInfoOptionKeys.includes(key) && metaInfo.hasOwnProperty(key)) { metaInfo[key] = generateServerInjector(options, key, metaInfo[key]); } @@ -1387,10 +1652,12 @@ function _inject(options = {}) { }; } -function _$meta(options = {}) { - const _refresh$1 = _refresh(options); +function _$meta() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - const _inject$1 = _inject(options); + var _refresh$1 = _refresh(options); + + var _inject$1 = _inject(options); /** * Returns an injector for server-side rendering. * @this {Object} - the Vue instance (a root component) @@ -1400,7 +1667,9 @@ function _$meta(options = {}) { return function $meta() { return { - getOptions: () => getOptions(options), + getOptions: function getOptions$1() { + return getOptions(options); + }, refresh: _refresh$1.bind(this), inject: _inject$1.bind(this), pause: pause.bind(this), @@ -1414,7 +1683,9 @@ function _$meta(options = {}) { * @param {Function} Vue - the Vue constructor. */ -function install(Vue, options = {}) { +function install(Vue) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (Vue.__vuemeta_installed) { return; } @@ -1426,9 +1697,9 @@ function install(Vue, options = {}) { } var index = { - version, - install, - hasMetaInfo + version: version, + install: install, + hasMetaInfo: hasMetaInfo }; module.exports = index; diff --git a/dist/vue-meta.esm.browser.js b/dist/vue-meta.esm.browser.js index 09d4d9a..6116f55 100644 --- a/dist/vue-meta.esm.browser.js +++ b/dist/vue-meta.esm.browser.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.1.0 + * vue-meta v2.1.1 * (c) 2019 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -9,12 +9,11 @@ import deepmerge from 'deepmerge'; -var version = "2.1.0"; +var version = "2.1.1"; // store an id to keep track of DOM updates -let batchId = null; - -function triggerUpdate (vm, hookName) { +var batchId = null; +function triggerUpdate(vm, hookName) { // if an update was triggered during initialization or when an update was triggered by the // metaInfo watcher, set initialized to null // then we keep falsy value but know we need to run a triggerUpdate after initialization @@ -24,10 +23,11 @@ function triggerUpdate (vm, hookName) { if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) { // batch potential DOM updates to prevent extraneous re-rendering - batchUpdate(() => vm.$meta().refresh()); + batchUpdate(function () { + return vm.$meta().refresh(); + }); } } - /** * Performs a batched update. * @@ -35,14 +35,135 @@ function triggerUpdate (vm, hookName) { * @param {Function} callback - the update to perform * @return {Number} id - a new ID */ -function batchUpdate (callback, timeout = 10) { - clearTimeout(batchId); - batchId = setTimeout(() => { +function batchUpdate(callback) { + var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; + clearTimeout(batchId); + batchId = setTimeout(function () { callback(); }, timeout); + return batchId; +} - return batchId +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + keys.push.apply(keys, symbols); + } + + return keys; +} + +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(source, true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(source).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; +} + +function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); } /** @@ -50,265 +171,263 @@ function batchUpdate (callback, timeout = 10) { * @param {any} arg - the object to check * @return {Boolean} - true if `arg` is an array */ -function isArray (arg) { - return Array.isArray(arg) +function isArray(arg) { + return Array.isArray(arg); +} +function isUndefined(arg) { + return typeof arg === 'undefined'; +} +function isObject(arg) { + return _typeof(arg) === 'object'; +} +function isPureObject(arg) { + return _typeof(arg) === 'object' && arg !== null; +} +function isFunction(arg) { + return typeof arg === 'function'; +} +function isString(arg) { + return typeof arg === 'string'; } -function isUndefined (arg) { - return typeof arg === 'undefined' -} - -function isObject (arg) { - return typeof arg === 'object' -} - -function isPureObject (arg) { - return typeof arg === 'object' && arg !== null -} - -function isFunction (arg) { - return typeof arg === 'function' -} - -function isString (arg) { - return typeof arg === 'string' -} - -function ensureIsArray (arg, key) { +function ensureIsArray(arg, key) { if (!key || !isObject(arg)) { - return isArray(arg) ? arg : [] + return isArray(arg) ? arg : []; } if (!isArray(arg[key])) { arg[key] = []; } - return arg + + return arg; } - -function ensuredPush (object, key, el) { +function ensuredPush(object, key, el) { ensureIsArray(object, key); - object[key].push(el); } -// Vue $root instance has a _vueMeta object property, otherwise its a boolean true -function hasMetaInfo (vm = this) { - return vm && (vm._vueMeta === true || isObject(vm._vueMeta)) +function hasMetaInfo() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; + return vm && (vm._vueMeta === true || isObject(vm._vueMeta)); +} // a component is in a metaInfo branch when itself has meta info or one of its (grand-)children has + +function inMetaInfoBranch() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; + return vm && !isUndefined(vm._vueMeta); } -// a component is in a metaInfo branch when itself has meta info or one of its (grand-)children has -function inMetaInfoBranch (vm = this) { - return vm && !isUndefined(vm._vueMeta) -} - -function addNavGuards (vm) { +function addNavGuards(vm) { // return when nav guards already added or no router exists if (vm.$root._vueMeta.navGuards || !vm.$root.$router) { /* istanbul ignore next */ - return + return; } vm.$root._vueMeta.navGuards = true; - - const $router = vm.$root.$router; - const $meta = vm.$root.$meta(); - - $router.beforeEach((to, from, next) => { + var $router = vm.$root.$router; + var $meta = vm.$root.$meta(); + $router.beforeEach(function (to, from, next) { $meta.pause(); next(); }); + $router.afterEach(function () { + var _$meta$resume = $meta.resume(), + metaInfo = _$meta$resume.metaInfo; - $router.afterEach(() => { - const { metaInfo } = $meta.resume(); if (metaInfo && metaInfo.afterNavigation && isFunction(metaInfo.afterNavigation)) { metaInfo.afterNavigation(metaInfo); } }); } -function hasGlobalWindowFn () { +function hasGlobalWindowFn() { try { - return !isUndefined(window) + return !isUndefined(window); } catch (e) { - return false + return false; } } +var hasGlobalWindow = hasGlobalWindowFn(); -const hasGlobalWindow = hasGlobalWindowFn(); +var _global = hasGlobalWindow ? window : global; -const _global = hasGlobalWindow ? window : global; - -const console = (_global.console = _global.console || {}); - -function warn (...args) { +var console = _global.console = _global.console || {}; +function warn() { /* istanbul ignore next */ if (!console || !console.warn) { - return + return; } - console.warn(...args); + console.warn.apply(console, arguments); } +var showWarningNotSupported = function showWarningNotSupported() { + return warn('This vue app/component has no vue-meta configuration'); +}; -const showWarningNotSupported = () => warn('This vue app/component has no vue-meta configuration'); - -let appId = 1; - -function createMixin (Vue, options) { +var appId = 1; +function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates - // watch for client side component updates return { - beforeCreate () { + beforeCreate: function beforeCreate() { + var _this = this; + Object.defineProperty(this, '_hasMetaInfo', { configurable: true, - get () { + get: function get() { // Show deprecation warning once when devtools enabled if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) { warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead'); this.$root._vueMeta.hasMetaInfoDeprecationWarningShown = true; } - return hasMetaInfo(this) - } - }); - // Add a marker to know if it uses metaInfo + return hasMetaInfo(this); + } + }); // Add a marker to know if it uses metaInfo // _vnode is used to know that it's attached to a real component // useful if we use some mixin to add some meta tags (like nuxt-i18n) + if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) { if (!this.$root._vueMeta) { - this.$root._vueMeta = { appId }; + this.$root._vueMeta = { + appId: appId + }; appId++; - } - - // to speed up updates we keep track of branches which have a component with vue-meta info defined + } // to speed up updates we keep track of branches which have a component with vue-meta info defined // if _vueMeta = true it has info, if _vueMeta = false a child has info + + if (!this._vueMeta) { this._vueMeta = true; + var p = this.$parent; - let p = this.$parent; while (p && p !== this.$root) { if (isUndefined(p._vueMeta)) { p._vueMeta = false; } + p = p.$parent; } - } - - // coerce function-style metaInfo to a computed prop so we can observe + } // coerce function-style metaInfo to a computed prop so we can observe // it on creation + + if (isFunction(this.$options[options.keyName])) { if (!this.$options.computed) { this.$options.computed = {}; } + this.$options.computed.$metaInfo = this.$options[options.keyName]; if (!this.$isServer) { // 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) - ensuredPush(this.$options, 'created', () => { - this.$watch('$metaInfo', function () { + ensuredPush(this.$options, 'created', function () { + _this.$watch('$metaInfo', function () { triggerUpdate(this, 'watcher'); }); }); } - } - - // force an initial refresh on page load and prevent other lifecycleHooks + } // 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 // has throttled rAF/timers we still immediately set the page title + + if (isUndefined(this.$root._vueMeta.initialized)) { this.$root._vueMeta.initialized = this.$isServer; if (!this.$root._vueMeta.initialized) { - ensuredPush(this.$options, 'beforeMount', () => { + ensuredPush(this.$options, 'beforeMount', function () { // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if (this.$root.$el && this.$root.$el.hasAttribute && this.$root.$el.hasAttribute('data-server-rendered')) { - this.$root._vueMeta.appId = options.ssrAppId; + if (_this.$root.$el && _this.$root.$el.hasAttribute && _this.$root.$el.hasAttribute('data-server-rendered')) { + _this.$root._vueMeta.appId = options.ssrAppId; } - }); + }); // we use the mounted hook here as on page load - // we use the mounted hook here as on page load - ensuredPush(this.$options, 'mounted', () => { - if (!this.$root._vueMeta.initialized) { + ensuredPush(this.$options, 'mounted', function () { + if (!_this.$root._vueMeta.initialized) { // used in triggerUpdate to check if a change was triggered // during initialization - this.$root._vueMeta.initializing = true; + _this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded - // refresh meta in nextTick so all child components have loaded - this.$nextTick(function () { - const { tags, metaInfo } = this.$root.$meta().refresh(); + _this.$nextTick(function () { + var _this2 = this; - // After ssr hydration (identifier by tags === false) check + var _this$$root$$meta$ref = this.$root.$meta().refresh(), + tags = _this$$root$$meta$ref.tags, + metaInfo = _this$$root$$meta$ref.metaInfo; // After ssr hydration (identifier by tags === false) check // if initialized was set to null in triggerUpdate. That'd mean // that during initilazation changes where triggered which need // to be applied OR a metaInfo watcher was triggered before the // current hook was called // (during initialization all changes are blocked) + + if (tags === false && this.$root._vueMeta.initialized === null) { - this.$nextTick(() => triggerUpdate(this, 'initializing')); + this.$nextTick(function () { + return triggerUpdate(_this2, 'initializing'); + }); } this.$root._vueMeta.initialized = true; - delete this.$root._vueMeta.initializing; - - // add the navigation guards if they havent been added yet + delete this.$root._vueMeta.initializing; // add the navigation guards if they havent been added yet // they are needed for the afterNavigation callback + if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { addNavGuards(this); } }); } - }); + }); // add the navigation guards if requested - // add the navigation guards if requested if (options.refreshOnceOnNavigation) { addNavGuards(this); } } - } + } // do not trigger refresh on the server side + - // do not trigger refresh on the server side if (!this.$isServer) { // no need to add this hooks on server side - updateOnLifecycleHook.forEach((lifecycleHook) => { - ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook)); - }); + updateOnLifecycleHook.forEach(function (lifecycleHook) { + ensuredPush(_this.$options, lifecycleHook, function () { + return triggerUpdate(_this, lifecycleHook); + }); + }); // re-render meta data when returning from a child component to parent - // re-render meta data when returning from a child component to parent - ensuredPush(this.$options, 'destroyed', () => { + ensuredPush(this.$options, 'destroyed', function () { // Wait that element is hidden before refreshing meta tags (to support animations) - const interval = setInterval(() => { - if (this.$el && this.$el.offsetParent !== null) { + var interval = setInterval(function () { + if (_this.$el && _this.$el.offsetParent !== null) { /* istanbul ignore next line */ - return + return; } clearInterval(interval); - if (!this.$parent) { + if (!_this.$parent) { /* istanbul ignore next line */ - return + return; } - triggerUpdate(this, 'destroyed'); + triggerUpdate(_this, 'destroyed'); }, 50); }); } } } - } + }; } /** * These are constant variables used throughout the application. */ - // set some sane defaults -const defaultInfo = { +var defaultInfo = { title: undefined, titleChunk: '', titleTemplate: '%s', @@ -322,175 +441,109 @@ const defaultInfo = { script: [], noscript: [], __dangerouslyDisableSanitizers: [], - __dangerouslyDisableSanitizersByTagID: {} + __dangerouslyDisableSanitizersByTagID: {} // This is the name of the component option that contains all the information that + // gets converted to the various meta tags & attributes for the page. + }; - -// This is the name of the component option that contains all the information that -// gets converted to the various meta tags & attributes for the page. -const keyName = 'metaInfo'; - -// This is the attribute vue-meta arguments on elements to know which it should +var keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should // manage and which it should ignore. -const attribute = 'data-vue-meta'; -// This is the attribute that goes on the `html` tag to inform `vue-meta` +var attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` // that the server has already generated the meta tags for the initial render. -const ssrAttribute = 'data-vue-meta-server-rendered'; -// This is the property that tells vue-meta to overwrite (instead of append) +var ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) // an item in a tag list. For example, if you have two `meta` tag list items // that both have `vmid` of "description", then vue-meta will overwrite the // shallowest one with the deepest one. -const tagIDKeyName = 'vmid'; -// This is the key name for possible meta templates -const metaTemplateKeyName = 'template'; +var tagIDKeyName = 'vmid'; // This is the key name for possible meta templates -// This is the key name for the content-holding property -const contentKeyName = 'content'; +var metaTemplateKeyName = 'template'; // This is the key name for the content-holding property -// The id used for the ssr app -const ssrAppId = 'ssr'; +var contentKeyName = 'content'; // The id used for the ssr app + +var ssrAppId = 'ssr'; +var defaultOptions = { + keyName: keyName, + attribute: attribute, + ssrAttribute: ssrAttribute, + tagIDKeyName: tagIDKeyName, + contentKeyName: contentKeyName, + metaTemplateKeyName: metaTemplateKeyName, + ssrAppId: ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) -const defaultOptions = { - keyName, - attribute, - ssrAttribute, - tagIDKeyName, - contentKeyName, - metaTemplateKeyName, - ssrAppId }; +var metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping -// List of metaInfo property keys which are configuration options (and dont generate html) -const metaInfoOptionKeys = [ - 'titleChunk', - 'titleTemplate', - 'changed', - '__dangerouslyDisableSanitizers', - '__dangerouslyDisableSanitizersByTagID' -]; +var disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags -// The metaInfo property keys which are used to disable escaping -const disableOptionKeys = [ - '__dangerouslyDisableSanitizers', - '__dangerouslyDisableSanitizersByTagID' -]; +var metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event -// List of metaInfo property keys which only generates attributes and no tags -const metaInfoAttributeKeys = [ - 'htmlAttrs', - 'headAttrs', - 'bodyAttrs' -]; +var tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) -// HTML elements which support the onload event -const tagsSupportingOnload = ['link', 'style', 'script']; +var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -// Attributes which should be added with data- prefix -const commonDataAttributes = ['body', 'pbody']; +var booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; -// from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -const booleanHtmlAttributes = [ - 'allowfullscreen', - 'amp', - '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' -]; - -function setOptions (options) { +function setOptions(options) { // combine options options = isObject(options) ? options : {}; - for (const key in defaultOptions) { + for (var key in defaultOptions) { if (!options[key]) { options[key] = defaultOptions[key]; } } - return options + return options; } +function getOptions(options) { + var optionsCopy = {}; -function getOptions (options) { - const optionsCopy = {}; - for (const key in options) { + for (var key in options) { optionsCopy[key] = options[key]; } - return optionsCopy + + return optionsCopy; } -function pause (refresh = true) { +function pause() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = true; - - return () => resume(refresh) + return function () { + return resume(refresh); + }; } - -function resume (refresh = true) { +function resume() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = false; if (refresh) { - return this.$root.$meta().refresh() + return this.$root.$meta().refresh(); } } -function applyTemplate ({ component, metaTemplateKeyName, contentKeyName }, headObject, template, chunk) { +function applyTemplate(_ref, headObject, template, chunk) { + var component = _ref.component, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; + if (isUndefined(template)) { template = headObject[metaTemplateKeyName]; delete headObject[metaTemplateKeyName]; - } + } // return early if no template defined + - // return early if no template defined if (!template) { - return false + return false; } if (isUndefined(chunk)) { chunk = headObject[contentKeyName]; } - headObject[contentKeyName] = isFunction(template) - ? template.call(component, chunk) - : template.replace(/%s/g, chunk); - - return true + headObject[contentKeyName] = isFunction(template) ? template.call(component, chunk) : template.replace(/%s/g, chunk); + return true; } /* @@ -501,78 +554,81 @@ function applyTemplate ({ component, metaTemplateKeyName, contentKeyName }, head * Also, only files in client/ & shared/ should use these functions * files in server/ still use normal js function */ +function findIndex(array, predicate) { -function findIndex (array, predicate) { - return array.findIndex(predicate, arguments[2]) + return array.findIndex(predicate, arguments[2]); +} +function toArray(arg) { + + return Array.from(arg); +} +function includes(array, value) { + + return array.includes(value); } -function toArray (arg) { - return Array.from(arg) -} +var clientSequences = [[/&/g, "&"], [/</g, "<"], [/>/g, ">"], [/"/g, "\""], [/'/g, "'"]]; // sanitizes potentially dangerous characters -function includes (array, value) { - return array.includes(value) -} +function escape(info, options, escapeOptions) { + var tagIDKeyName = options.tagIDKeyName; + var _escapeOptions$doEsca = escapeOptions.doEscape, + doEscape = _escapeOptions$doEsca === void 0 ? function (v) { + return v; + } : _escapeOptions$doEsca, + escapeKeys = escapeOptions.escapeKeys; + var escaped = {}; -const clientSequences = [ - [/&/g, '\u0026'], - [/</g, '\u003C'], - [/>/g, '\u003E'], - [/"/g, '\u0022'], - [/'/g, '\u0027'] -]; + for (var key in info) { + var value = info[key]; // no need to escape configuration options -// sanitizes potentially dangerous characters -function escape (info, options, escapeOptions) { - const { tagIDKeyName } = options; - const { doEscape = v => v, escapeKeys } = escapeOptions; - const escaped = {}; - - for (const key in info) { - const value = info[key]; - - // no need to escape configuration options if (includes(metaInfoOptionKeys, key)) { escaped[key] = value; - continue + continue; } - let [ disableKey ] = disableOptionKeys; + var _disableOptionKeys = _slicedToArray(disableOptionKeys, 1), + disableKey = _disableOptionKeys[0]; + if (escapeOptions[disableKey] && includes(escapeOptions[disableKey], key)) { // this info[key] doesnt need to escaped if the option is listed in __dangerouslyDisableSanitizers escaped[key] = value; - continue + continue; } - const tagId = info[tagIDKeyName]; + var tagId = info[tagIDKeyName]; + if (tagId) { - disableKey = disableOptionKeys[1]; + disableKey = disableOptionKeys[1]; // keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped - // keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped if (escapeOptions[disableKey] && escapeOptions[disableKey][tagId] && includes(escapeOptions[disableKey][tagId], key)) { escaped[key] = value; - continue + continue; } } if (isString(value)) { escaped[key] = doEscape(value); } else if (isArray(value)) { - escaped[key] = value.map((v) => { + escaped[key] = value.map(function (v) { if (isPureObject(v)) { - return escape(v, options, { ...escapeOptions, escapeKeys: true }) + return escape(v, options, _objectSpread2({}, escapeOptions, { + escapeKeys: true + })); } - return doEscape(v) + return doEscape(v); }); } else if (isPureObject(value)) { - escaped[key] = escape(value, options, { ...escapeOptions, escapeKeys: true }); + escaped[key] = escape(value, options, _objectSpread2({}, escapeOptions, { + escapeKeys: true + })); } else { escaped[key] = value; } if (escapeKeys) { - const escapedKey = doEscape(key); + var escapedKey = doEscape(key); + if (key !== escapedKey) { escaped[escapedKey] = escaped[key]; delete escaped[key]; @@ -580,72 +636,83 @@ function escape (info, options, escapeOptions) { } } - return escaped + return escaped; } -function arrayMerge ({ component, tagIDKeyName, metaTemplateKeyName, contentKeyName }, target, source) { +function _arrayMerge(_ref, target, source) { + var component = _ref.component, + tagIDKeyName = _ref.tagIDKeyName, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; // we concat the arrays without merging objects contained in, // but we check for a `vmid` property on each object in the array // using an O(1) lookup associative array exploit - const destination = []; - - target.forEach((targetItem, targetIndex) => { + var destination = []; + target.forEach(function (targetItem, targetIndex) { // no tagID so no need to check for duplicity if (!targetItem[tagIDKeyName]) { destination.push(targetItem); - return + return; } - const sourceIndex = findIndex(source, item => item[tagIDKeyName] === targetItem[tagIDKeyName]); - const sourceItem = source[sourceIndex]; + var sourceIndex = findIndex(source, function (item) { + return item[tagIDKeyName] === targetItem[tagIDKeyName]; + }); + var sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem - // source doesnt contain any duplicate vmid's, we can keep targetItem if (sourceIndex === -1) { destination.push(targetItem); - return - } - - // when sourceItem explictly defines contentKeyName or innerHTML as undefined, its + return; + } // when sourceItem explictly defines contentKeyName or innerHTML as undefined, its // an indication that we need to skip the default behaviour or child has preference over parent // which means we keep the targetItem and ignore/remove the sourceItem - if ((sourceItem.hasOwnProperty(contentKeyName) && sourceItem[contentKeyName] === undefined) || - (sourceItem.hasOwnProperty('innerHTML') && sourceItem.innerHTML === undefined)) { - destination.push(targetItem); - // remove current index from source array so its not concatenated to destination below + + + if (sourceItem.hasOwnProperty(contentKeyName) && sourceItem[contentKeyName] === undefined || sourceItem.hasOwnProperty('innerHTML') && sourceItem.innerHTML === undefined) { + destination.push(targetItem); // remove current index from source array so its not concatenated to destination below + source.splice(sourceIndex, 1); - return - } - - // we now know that targetItem is a duplicate and we should ignore it in favor of sourceItem - + return; + } // we now know that targetItem is a duplicate and we should ignore it in favor of sourceItem // if source specifies null as content then ignore both the target as the source + + if (sourceItem[contentKeyName] === null || sourceItem.innerHTML === null) { // remove current index from source array so its not concatenated to destination below source.splice(sourceIndex, 1); - return - } + return; + } // now we only need to check if the target has a template to combine it with the source + + + var targetTemplate = targetItem[metaTemplateKeyName]; - // now we only need to check if the target has a template to combine it with the source - const targetTemplate = targetItem[metaTemplateKeyName]; if (!targetTemplate) { - return + return; } - const sourceTemplate = sourceItem[metaTemplateKeyName]; + var sourceTemplate = sourceItem[metaTemplateKeyName]; if (!sourceTemplate) { // use parent template and child content - applyTemplate({ component, metaTemplateKeyName, contentKeyName }, sourceItem, targetTemplate); + applyTemplate({ + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName + }, sourceItem, targetTemplate); } else if (!sourceItem[contentKeyName]) { // use child template and parent content - applyTemplate({ component, metaTemplateKeyName, contentKeyName }, sourceItem, undefined, targetItem[contentKeyName]); + applyTemplate({ + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName + }, sourceItem, undefined, targetItem[contentKeyName]); } }); - - return destination.concat(source) + return destination.concat(source); } +function merge(target, source) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; -function merge (target, source, options = {}) { // remove properties explicitly set to false so child components can // optionally _not_ overwrite the parents content // (for array properties this is checked in arrayMerge) @@ -653,24 +720,26 @@ function merge (target, source, options = {}) { delete source.title; } - metaInfoAttributeKeys.forEach((attrKey) => { + metaInfoAttributeKeys.forEach(function (attrKey) { if (!source[attrKey]) { - return + return; } - for (const key in source[attrKey]) { + for (var key in source[attrKey]) { if (source[attrKey].hasOwnProperty(key) && source[attrKey][key] === undefined) { if (includes(booleanHtmlAttributes, key)) { warn('VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details'); } + delete source[attrKey][key]; } } }); - return deepmerge(target, source, { - arrayMerge: (t, s) => arrayMerge(options, t, s) - }) + arrayMerge: function arrayMerge(t, s) { + return _arrayMerge(options, t, s); + } + }); } /** @@ -687,39 +756,45 @@ function merge (target, source, options = {}) { * @param {Object} [result={}] - result so far * @return {Object} result - final aggregated result */ -function getComponentOption (options = {}, component, result = {}) { - const { keyName, metaTemplateKeyName, tagIDKeyName } = options; - const { $options, $children } = component; + +function getComponentOption() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var keyName = options.keyName, + metaTemplateKeyName = options.metaTemplateKeyName, + tagIDKeyName = options.tagIDKeyName; + var $options = component.$options, + $children = component.$children; if (component._inactive) { - return result - } + return result; + } // only collect option data if it exists + - // only collect option data if it exists if ($options[keyName]) { - let data = $options[keyName]; + var data = $options[keyName]; // if option is a function, replace it with it's result - // if option is a function, replace it with it's result if (isFunction(data)) { data = data.call(component); - } + } // ignore data if its not an object, then we keep our previous result + - // ignore data if its not an object, then we keep our previous result if (!isObject(data)) { - return result - } + return result; + } // merge with existing options + - // merge with existing options result = merge(result, data, options); - } + } // collect & aggregate child options if deep = true + - // collect & aggregate child options if deep = true if ($children.length) { - $children.forEach((childComponent) => { + $children.forEach(function (childComponent) { // check if the childComponent is in a branch // return otherwise so we dont walk all component branches unnecessarily if (!inMetaInfoBranch(childComponent)) { - return + return; } result = getComponentOption(options, childComponent, result); @@ -728,20 +803,21 @@ function getComponentOption (options = {}, component, result = {}) { if (metaTemplateKeyName && result.meta) { // apply templates if needed - result.meta.forEach(metaObject => applyTemplate(options, metaObject)); + result.meta.forEach(function (metaObject) { + return applyTemplate(options, metaObject); + }); // remove meta items with duplicate vmid's - // remove meta items with duplicate vmid's - result.meta = result.meta.filter((metaItem, index, arr) => { - return ( - // keep meta item if it doesnt has a vmid - !metaItem.hasOwnProperty(tagIDKeyName) || - // or if it's the first item in the array with this vmid - index === findIndex(arr, item => item[tagIDKeyName] === metaItem[tagIDKeyName]) - ) + result.meta = result.meta.filter(function (metaItem, index, arr) { + return (// keep meta item if it doesnt has a vmid + !metaItem.hasOwnProperty(tagIDKeyName) || // or if it's the first item in the array with this vmid + index === findIndex(arr, function (item) { + return item[tagIDKeyName] === metaItem[tagIDKeyName]; + }) + ); }); } - return result + return result; } /** @@ -751,132 +827,164 @@ function getComponentOption (options = {}, component, result = {}) { * @param {Object} component - the Vue instance to get meta info from * @return {Object} - returned meta info */ -function getMetaInfo (options = {}, component, escapeSequences = []) { + +function getMetaInfo() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var escapeSequences = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; // collect & aggregate all metaInfo $options - let info = getComponentOption(options, component, defaultInfo); - - // Remove all "template" tags from meta - + var info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta // backup the title chunk in case user wants access to it + if (info.title) { info.titleChunk = info.title; - } + } // replace title with populated template + - // replace title with populated template if (info.titleTemplate && info.titleTemplate !== '%s') { - applyTemplate({ component, contentKeyName: 'title' }, info, info.titleTemplate, info.titleChunk || ''); - } - - // convert base tag to an array so it can be handled the same way + applyTemplate({ + component: component, + contentKeyName: 'title' + }, info, info.titleTemplate, info.titleChunk || ''); + } // convert base tag to an array so it can be handled the same way // as the other tags + + if (info.base) { info.base = Object.keys(info.base).length ? [info.base] : []; } - const escapeOptions = { - doEscape: value => escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value) - }; + var escapeOptions = { + doEscape: function doEscape(value) { + return escapeSequences.reduce(function (val, _ref) { + var _ref2 = _slicedToArray(_ref, 2), + v = _ref2[0], + r = _ref2[1]; - disableOptionKeys.forEach((disableKey, index) => { + return val.replace(v, r); + }, value); + } + }; + disableOptionKeys.forEach(function (disableKey, index) { if (index === 0) { ensureIsArray(info, disableKey); } else if (index === 1) { - for (const key in info[disableKey]) { + for (var key in info[disableKey]) { ensureIsArray(info[disableKey], key); } } escapeOptions[disableKey] = info[disableKey]; - }); + }); // begin sanitization - // begin sanitization info = escape(info, options, escapeOptions); - - return info + return info; } -function getTag (tags, tag) { +function getTag(tags, tag) { if (!tags[tag]) { tags[tag] = document.getElementsByTagName(tag)[0]; } - return tags[tag] + return tags[tag]; } - -function getElementsKey ({ body, pbody }) { - return body - ? 'body' - : (pbody ? 'pbody' : 'head') +function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; + return body ? 'body' : pbody ? 'pbody' : 'head'; } - -function queryElements (parentNode, { appId, attribute, type, tagIDKeyName }, attributes = {}) { - const queries = [ - `${type}[${attribute}="${appId}"]`, - `${type}[data-${tagIDKeyName}]` - ].map((query) => { - for (const key in attributes) { - const val = attributes[key]; - const attributeValue = val && val !== true ? `="${val}"` : ''; - query += `[data-${key}${attributeValue}]`; +function queryElements(parentNode, _ref2) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var queries = ["".concat(type, "[").concat(attribute, "=\"").concat(appId, "\"]"), "".concat(type, "[data-").concat(tagIDKeyName, "]")].map(function (query) { + for (var key in attributes) { + var val = attributes[key]; + var attributeValue = val && val !== true ? "=\"".concat(val, "\"") : ''; + query += "[data-".concat(key).concat(attributeValue, "]"); } - return query + + return query; }); - - return toArray(parentNode.querySelectorAll(queries.join(', '))) + return toArray(parentNode.querySelectorAll(queries.join(', '))); } -const callbacks = []; - -function isDOMComplete (d = document) { - return d.readyState === 'complete' +var callbacks = []; +function isDOMComplete() { + var d = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; + return d.readyState === 'complete'; } - -function addCallback (query, callback) { +function addCallback(query, callback) { if (arguments.length === 1) { callback = query; query = ''; } - callbacks.push([ query, callback ]); + callbacks.push([query, callback]); } +function addCallbacks(_ref, type, tags, autoAddListeners) { + var tagIDKeyName = _ref.tagIDKeyName; + var hasAsyncCallback = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; -function addCallbacks ({ tagIDKeyName }, type, tags, autoAddListeners) { - let hasAsyncCallback = false; + try { + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var tag = _step.value; - for (const tag of tags) { - if (!tag[tagIDKeyName] || !tag.callback) { - continue + if (!tag[tagIDKeyName] || !tag.callback) { + continue; + } + + hasAsyncCallback = true; + addCallback("".concat(type, "[data-").concat(tagIDKeyName, "=\"").concat(tag[tagIDKeyName], "\"]"), tag.callback); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } - - hasAsyncCallback = true; - addCallback(`${type}[data-${tagIDKeyName}="${tag[tagIDKeyName]}"]`, tag.callback); } if (!autoAddListeners || !hasAsyncCallback) { - return hasAsyncCallback + return hasAsyncCallback; } - return addListeners() + return addListeners(); } - -function addListeners () { +function addListeners() { if (isDOMComplete()) { applyCallbacks(); - return - } + return; + } // Instead of using a MutationObserver, we just apply - // Instead of using a MutationObserver, we just apply /* istanbul ignore next */ - document.onreadystatechange = () => { + + + document.onreadystatechange = function () { applyCallbacks(); }; } +function applyCallbacks(matchElement) { + var _loop = function _loop() { + var _callbacks$_i = _slicedToArray(_callbacks[_i], 2), + query = _callbacks$_i[0], + callback = _callbacks$_i[1]; -function applyCallbacks (matchElement) { - for (const [query, callback] of callbacks) { - const selector = `${query}[onload="this.__vm_l=1"]`; + var selector = "".concat(query, "[onload=\"this.__vm_l=1\"]"); + var elements = []; - let elements = []; if (!matchElement) { elements = toArray(document.querySelectorAll(selector)); } @@ -885,48 +993,78 @@ function applyCallbacks (matchElement) { elements = [matchElement]; } - for (const element of elements) { - /* __vm_cb: whether the load callback has been called - * __vm_l: set by onload attribute, whether the element was loaded - * __vm_ev: whether the event listener was added or not - */ - if (element.__vm_cb) { - continue - } + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; - const onload = () => { - /* Mark that the callback for this element has already been called, - * this prevents the callback to run twice in some (rare) conditions + try { + var _loop2 = function _loop2() { + var element = _step2.value; + + /* __vm_cb: whether the load callback has been called + * __vm_l: set by onload attribute, whether the element was loaded + * __vm_ev: whether the event listener was added or not */ - element.__vm_cb = true; + if (element.__vm_cb) { + return "continue"; + } - /* onload needs to be removed because we only need the - * attribute after ssr and if we dont remove it the node - * will fail isEqualNode on the client + var onload = function onload() { + /* Mark that the callback for this element has already been called, + * this prevents the callback to run twice in some (rare) conditions + */ + element.__vm_cb = true; + /* onload needs to be removed because we only need the + * attribute after ssr and if we dont remove it the node + * will fail isEqualNode on the client + */ + + element.removeAttribute('onload'); + callback(element); + }; + /* IE9 doesnt seem to load scripts synchronously, + * causing a script sometimes/often already to be loaded + * when we add the event listener below (thus adding an onload event + * listener has no use because it will never be triggered). + * Therefore we add the onload attribute during ssr, and + * check here if it was already loaded or not */ - element.removeAttribute('onload'); - callback(element); + + if (element.__vm_l) { + onload(); + return "continue"; + } + + if (!element.__vm_ev) { + element.__vm_ev = true; + element.addEventListener('load', onload); + } }; - /* IE9 doesnt seem to load scripts synchronously, - * causing a script sometimes/often already to be loaded - * when we add the event listener below (thus adding an onload event - * listener has no use because it will never be triggered). - * Therefore we add the onload attribute during ssr, and - * check here if it was already loaded or not - */ - if (element.__vm_l) { - onload(); - continue + for (var _iterator2 = elements[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var _ret = _loop2(); + + if (_ret === "continue") continue; } - - if (!element.__vm_ev) { - element.__vm_ev = true; - - element.addEventListener('load', onload); + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } } } + }; + + for (var _i = 0, _callbacks = callbacks; _i < _callbacks.length; _i++) { + _loop(); } } @@ -936,40 +1074,43 @@ function applyCallbacks (matchElement) { * @param {Object} attrs - the new document html attributes * @param {HTMLElement} tag - the HTMLElement tag to update with new attrs */ -function updateAttribute ({ attribute } = {}, attrs, tag) { - const vueMetaAttrString = tag.getAttribute(attribute); - const vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; - const toRemove = toArray(vueMetaAttrs); - const keepIndexes = []; - for (const attr in attrs) { +function updateAttribute() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute; + + var attrs = arguments.length > 1 ? arguments[1] : undefined; + var tag = arguments.length > 2 ? arguments[2] : undefined; + var vueMetaAttrString = tag.getAttribute(attribute); + var vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; + var toRemove = toArray(vueMetaAttrs); + var keepIndexes = []; + + for (var attr in attrs) { if (attrs.hasOwnProperty(attr)) { - const value = includes(booleanHtmlAttributes, attr) - ? '' - : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; - + var value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; tag.setAttribute(attr, value || ''); if (!includes(vueMetaAttrs, attr)) { vueMetaAttrs.push(attr); - } + } // filter below wont ever check -1 + - // filter below wont ever check -1 keepIndexes.push(toRemove.indexOf(attr)); } } - const removedAttributesCount = toRemove - .filter((el, index) => !includes(keepIndexes, index)) - .reduce((acc, attr) => { - tag.removeAttribute(attr); - return acc + 1 - }, 0); + var removedAttributesCount = toRemove.filter(function (el, index) { + return !includes(keepIndexes, index); + }).reduce(function (acc, attr) { + tag.removeAttribute(attr); + return acc + 1; + }, 0); if (vueMetaAttrs.length === removedAttributesCount) { tag.removeAttribute(attribute); } else { - tag.setAttribute(attribute, (vueMetaAttrs.sort()).join(',')); + tag.setAttribute(attribute, vueMetaAttrs.sort().join(',')); } } @@ -978,9 +1119,9 @@ function updateAttribute ({ attribute } = {}, attrs, tag) { * * @param {String} title - the new title of the document */ -function updateTitle (title) { +function updateTitle(title) { if (!title && title !== '') { - return + return; } document.title = title; @@ -994,134 +1135,185 @@ function updateTitle (title) { * @param {(Array<Object>|Object)} tags - an array of tag objects or a single object in case of base * @return {Object} - a representation of what tags changed */ -function updateTag (appId, options = {}, type, tags, head, body) { - const { attribute, tagIDKeyName } = options; - const dataAttributes = [tagIDKeyName, ...commonDataAttributes]; - const newElements = []; - - const queryOptions = { appId, attribute, type, tagIDKeyName }; - const currentElements = { +function updateTag(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var type = arguments.length > 2 ? arguments[2] : undefined; + var tags = arguments.length > 3 ? arguments[3] : undefined; + var head = arguments.length > 4 ? arguments[4] : undefined; + var body = arguments.length > 5 ? arguments[5] : undefined; + var attribute = options.attribute, + tagIDKeyName = options.tagIDKeyName; + var dataAttributes = [tagIDKeyName].concat(_toConsumableArray(commonDataAttributes)); + var newElements = []; + var queryOptions = { + appId: appId, + attribute: attribute, + type: type, + tagIDKeyName: tagIDKeyName + }; + var currentElements = { head: queryElements(head, queryOptions), - pbody: queryElements(body, queryOptions, { pbody: true }), - body: queryElements(body, queryOptions, { body: true }) + pbody: queryElements(body, queryOptions, { + pbody: true + }), + body: queryElements(body, queryOptions, { + body: true + }) }; if (tags.length > 1) { // remove duplicates that could have been found by merging tags // which include a mixin with metaInfo and that mixin is used // by multiple components on the same page - const found = []; - tags = tags.filter((x) => { - const k = JSON.stringify(x); - const res = !includes(found, k); + var found = []; + tags = tags.filter(function (x) { + var k = JSON.stringify(x); + var res = !includes(found, k); found.push(k); - return res + return res; }); } if (tags.length) { - for (const tag of tags) { - if (tag.skip) { - continue - } + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - const newElement = document.createElement(type); - newElement.setAttribute(attribute, appId); + try { + var _loop = function _loop() { + var tag = _step.value; - for (const attr in tag) { - /* istanbul ignore next */ - if (!tag.hasOwnProperty(attr)) { - continue + if (tag.skip) { + return "continue"; } - if (attr === 'innerHTML') { - newElement.innerHTML = tag.innerHTML; - continue - } + var newElement = document.createElement(type); + newElement.setAttribute(attribute, appId); - if (attr === 'json') { - newElement.innerHTML = JSON.stringify(tag.json); - continue - } - - if (attr === 'cssText') { - if (newElement.styleSheet) { - /* istanbul ignore next */ - newElement.styleSheet.cssText = tag.cssText; - } else { - newElement.appendChild(document.createTextNode(tag.cssText)); + var _loop2 = function _loop2(attr) { + /* istanbul ignore next */ + if (!tag.hasOwnProperty(attr)) { + return "continue"; } - continue + + if (attr === 'innerHTML') { + newElement.innerHTML = tag.innerHTML; + return "continue"; + } + + if (attr === 'json') { + newElement.innerHTML = JSON.stringify(tag.json); + return "continue"; + } + + if (attr === 'cssText') { + if (newElement.styleSheet) { + /* istanbul ignore next */ + newElement.styleSheet.cssText = tag.cssText; + } else { + newElement.appendChild(document.createTextNode(tag.cssText)); + } + + return "continue"; + } + + if (attr === 'callback') { + newElement.onload = function () { + return tag[attr](newElement); + }; + + return "continue"; + } + + var _attr = includes(dataAttributes, attr) ? "data-".concat(attr) : attr; + + var isBooleanAttribute = includes(booleanHtmlAttributes, attr); + + if (isBooleanAttribute && !tag[attr]) { + return "continue"; + } + + var value = isBooleanAttribute ? '' : tag[attr]; + newElement.setAttribute(_attr, value); + }; + + for (var attr in tag) { + var _ret2 = _loop2(attr); + + if (_ret2 === "continue") continue; } - if (attr === 'callback') { - newElement.onload = () => tag[attr](newElement); - continue + var oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. + + var indexToDelete = void 0; + var hasEqualElement = oldElements.some(function (existingTag, index) { + indexToDelete = index; + return newElement.isEqualNode(existingTag); + }); + + if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { + oldElements.splice(indexToDelete, 1); + } else { + newElements.push(newElement); } + }; - const _attr = includes(dataAttributes, attr) - ? `data-${attr}` - : attr; + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _ret = _loop(); - const isBooleanAttribute = includes(booleanHtmlAttributes, attr); - if (isBooleanAttribute && !tag[attr]) { - continue - } - - const value = isBooleanAttribute ? '' : tag[attr]; - newElement.setAttribute(_attr, value); + if (_ret === "continue") continue; } - - const oldElements = currentElements[getElementsKey(tag)]; - - // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - let indexToDelete; - const hasEqualElement = oldElements.some((existingTag, index) => { - indexToDelete = index; - return newElement.isEqualNode(existingTag) - }); - - if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { - oldElements.splice(indexToDelete, 1); - } else { - newElements.push(newElement); + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } } - let oldElements = []; - for (const current of Object.values(currentElements)) { - oldElements = [ - ...oldElements, - ...current - ]; - } + var oldElements = []; - // remove old elements - for (const element of oldElements) { + for (var _i = 0, _Object$values = Object.values(currentElements); _i < _Object$values.length; _i++) { + var current = _Object$values[_i]; + oldElements = [].concat(_toConsumableArray(oldElements), _toConsumableArray(current)); + } // remove old elements + + + for (var _i2 = 0, _oldElements = oldElements; _i2 < _oldElements.length; _i2++) { + var element = _oldElements[_i2]; element.parentNode.removeChild(element); - } + } // insert new elements - // insert new elements - for (const element of newElements) { - if (element.hasAttribute('data-body')) { - body.appendChild(element); - continue + + for (var _i3 = 0, _newElements = newElements; _i3 < _newElements.length; _i3++) { + var _element = _newElements[_i3]; + + if (_element.hasAttribute('data-body')) { + body.appendChild(_element); + continue; } - if (element.hasAttribute('data-pbody')) { - body.insertBefore(element, body.firstChild); - continue + if (_element.hasAttribute('data-pbody')) { + body.insertBefore(_element, body.firstChild); + continue; } - head.appendChild(element); + head.appendChild(_element); } return { oldTags: oldElements, newTags: newElements - } + }; } /** @@ -1129,24 +1321,45 @@ function updateTag (appId, options = {}, type, tags, head, body) { * * @param {Object} newInfo - the meta info to update to */ -function updateClientMetaInfo (appId, options = {}, newInfo) { - const { ssrAttribute, ssrAppId } = options; - // only cache tags for current update - const tags = {}; +function updateClientMetaInfo(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var newInfo = arguments.length > 2 ? arguments[2] : undefined; + var ssrAttribute = options.ssrAttribute, + ssrAppId = options.ssrAppId; // only cache tags for current update - const htmlTag = getTag(tags, 'html'); + var tags = {}; + var htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update - // if this is a server render, then dont update if (appId === ssrAppId && htmlTag.hasAttribute(ssrAttribute)) { // remove the server render attribute so we can update on (next) changes - htmlTag.removeAttribute(ssrAttribute); + htmlTag.removeAttribute(ssrAttribute); // add load callbacks if the - // add load callbacks if the - let addLoadListeners = false; - for (const type of tagsSupportingOnload) { - if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { - addLoadListeners = true; + var addLoadListeners = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = tagsSupportingOnload[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var type = _step.value; + + if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { + addLoadListeners = true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } @@ -1154,55 +1367,56 @@ function updateClientMetaInfo (appId, options = {}, newInfo) { addListeners(); } - return false - } + return false; + } // initialize tracked changes - // initialize tracked changes - const addedTags = {}; - const removedTags = {}; - for (const type in newInfo) { + var addedTags = {}; + var removedTags = {}; + + for (var _type in newInfo) { // ignore these - if (includes(metaInfoOptionKeys, type)) { - continue + if (includes(metaInfoOptionKeys, _type)) { + continue; } - if (type === 'title') { + if (_type === 'title') { // update the title updateTitle(newInfo.title); - continue + continue; } - if (includes(metaInfoAttributeKeys, type)) { - const tagName = type.substr(0, 4); - updateAttribute(options, newInfo[type], getTag(tags, tagName)); - continue + if (includes(metaInfoAttributeKeys, _type)) { + var tagName = _type.substr(0, 4); + + updateAttribute(options, newInfo[_type], getTag(tags, tagName)); + continue; + } // tags should always be an array, ignore if it isnt + + + if (!isArray(newInfo[_type])) { + continue; } - // tags should always be an array, ignore if it isnt - if (!isArray(newInfo[type])) { - continue - } - - const { oldTags, newTags } = updateTag( - appId, - options, - type, - newInfo[type], - getTag(tags, 'head'), - getTag(tags, 'body') - ); + var _updateTag = updateTag(appId, options, _type, newInfo[_type], getTag(tags, 'head'), getTag(tags, 'body')), + oldTags = _updateTag.oldTags, + newTags = _updateTag.newTags; if (newTags.length) { - addedTags[type] = newTags; - removedTags[type] = oldTags; + addedTags[_type] = newTags; + removedTags[_type] = oldTags; } } - return { addedTags, removedTags } + return { + addedTags: addedTags, + removedTags: removedTags + }; } -function _refresh (options = {}) { +function _refresh() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** * When called, will update the current meta info with new meta info. * Useful when updating meta info as the result of an asynchronous @@ -1213,30 +1427,37 @@ function _refresh (options = {}) { * * @return {Object} - new meta info */ - return function refresh () { - const metaInfo = getMetaInfo(options, this.$root, clientSequences); + return function refresh() { + var metaInfo = getMetaInfo(options, this.$root, clientSequences); + var appId = this.$root._vueMeta.appId; + var tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info - 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); } - return { vm: this, metaInfo, tags } - } + return { + vm: this, + metaInfo: metaInfo, + tags: tags + }; + }; } -function _$meta (options = {}) { - const _refresh$1 = _refresh(options); - const inject = () => {}; +function _$meta() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var _refresh$1 = _refresh(options); + + var inject = function inject() {}; /** * Returns an injector for server-side rendering. * @this {Object} - the Vue instance (a root component) * @return {Object} - injector */ - return function $meta () { + + + return function $meta() { if (!this.$root._vueMeta) { return { getOptions: showWarningNotSupported, @@ -1244,46 +1465,49 @@ function _$meta (options = {}) { inject: showWarningNotSupported, pause: showWarningNotSupported, resume: showWarningNotSupported - } + }; } return { - getOptions: () => getOptions(options), + getOptions: function getOptions$1() { + return getOptions(options); + }, refresh: _refresh$1.bind(this), - inject, + inject: inject, pause: pause.bind(this), resume: resume.bind(this) - } - } + }; + }; } /** * Plugin install function. * @param {Function} Vue - the Vue constructor. */ -function install (Vue, options = {}) { + +function install(Vue) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (Vue.__vuemeta_installed) { - return + return; } + Vue.__vuemeta_installed = true; - options = setOptions(options); - Vue.prototype.$meta = _$meta(options); - Vue.mixin(createMixin(Vue, options)); -} +} // automatic install + -// automatic install if (!isUndefined(window) && !isUndefined(window.Vue)) { /* istanbul ignore next */ install(window.Vue); } var browser = { - version, - install, - hasMetaInfo + version: version, + install: install, + hasMetaInfo: hasMetaInfo }; export default browser; diff --git a/dist/vue-meta.esm.browser.min.js b/dist/vue-meta.esm.browser.min.js index 0b0749e..c7cb2fa 100644 --- a/dist/vue-meta.esm.browser.min.js +++ b/dist/vue-meta.esm.browser.min.js @@ -1 +1 @@ -import t from"deepmerge";let e=null;function n(t,n){t.$root._vueMeta.initialized||!t.$root._vueMeta.initializing&&"watcher"!==n||(t.$root._vueMeta.initialized=null),t.$root._vueMeta.initialized&&!t.$root._vueMeta.paused&&function(t,n=10){clearTimeout(e),e=setTimeout(()=>{t()},n)}(()=>t.$meta().refresh())}function o(t){return Array.isArray(t)}function i(t){return void 0===t}function a(t){return"object"==typeof t}function r(t){return"object"==typeof t&&null!==t}function s(t){return"function"==typeof t}function u(t,e){return e&&a(t)?(o(t[e])||(t[e]=[]),t):o(t)?t:[]}function c(t,e,n){u(t,e),t[e].push(n)}function l(t=this){return t&&(!0===t._vueMeta||a(t._vueMeta))}function d(t){if(t.$root._vueMeta.navGuards||!t.$root.$router)return;t.$root._vueMeta.navGuards=!0;const e=t.$root.$router,n=t.$root.$meta();e.beforeEach((t,e,o)=>{n.pause(),o()}),e.afterEach(()=>{const{metaInfo:t}=n.resume();t&&t.afterNavigation&&s(t.afterNavigation)&&t.afterNavigation(t)})}const f=function(){try{return!i(window)}catch(t){return!1}}()?window:global,h=f.console=f.console||{};function p(...t){h&&h.warn&&h.warn(...t)}const m=()=>p("This vue app/component has no vue-meta configuration");let v=1;const y={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},$={keyName:"metaInfo",attribute:"data-vue-meta",ssrAttribute:"data-vue-meta-server-rendered",tagIDKeyName:"vmid",contentKeyName:"content",metaTemplateKeyName:"template",ssrAppId:"ssr"},b=["titleChunk","titleTemplate","changed","__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],g=["__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],_=["htmlAttrs","headAttrs","bodyAttrs"],M=["link","style","script"],T=["body","pbody"],N=["allowfullscreen","amp","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"];function I(t=!0){return this.$root._vueMeta.paused=!0,()=>A(t)}function A(t=!0){if(this.$root._vueMeta.paused=!1,t)return this.$root.$meta().refresh()}function w({component:t,metaTemplateKeyName:e,contentKeyName:n},o,a,r){return i(a)&&(a=o[e],delete o[e]),!!a&&(i(r)&&(r=o[n]),o[n]=s(a)?a.call(t,r):a.replace(/%s/g,r),!0)}function K(t,e){return t.findIndex(e,arguments[2])}function k(t){return Array.from(t)}function z(t,e){return t.includes(e)}const D=[[/&/g,"&"],[/</g,"<"],[/>/g,">"],[/"/g,'"'],[/'/g,"'"]];function O(e,n,o={}){return n.hasOwnProperty("title")&&void 0===n.title&&delete n.title,_.forEach(t=>{if(n[t])for(const e in n[t])n[t].hasOwnProperty(e)&&void 0===n[t][e]&&(z(N,e)&&p("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),delete n[t][e])}),t(e,n,{arrayMerge:(t,e)=>(function({component:t,tagIDKeyName:e,metaTemplateKeyName:n,contentKeyName:o},i,a){const r=[];return i.forEach((i,s)=>{if(!i[e])return void r.push(i);const u=K(a,t=>t[e]===i[e]),c=a[u];if(-1===u)return void r.push(i);if(c.hasOwnProperty(o)&&void 0===c[o]||c.hasOwnProperty("innerHTML")&&void 0===c.innerHTML)return r.push(i),void a.splice(u,1);if(null===c[o]||null===c.innerHTML)return void a.splice(u,1);const l=i[n];l&&(c[n]?c[o]||w({component:t,metaTemplateKeyName:n,contentKeyName:o},c,void 0,i[o]):w({component:t,metaTemplateKeyName:n,contentKeyName:o},c,l))}),r.concat(a)})(o,t,e)})}function S(t={},e,n={}){const{keyName:o,metaTemplateKeyName:r,tagIDKeyName:u}=t,{$options:c,$children:l}=e;if(e._inactive)return n;if(c[o]){let i=c[o];if(s(i)&&(i=i.call(e)),!a(i))return n;n=O(n,i,t)}return l.length&&l.forEach(e=>{(function(t=this){return t&&!i(t._vueMeta)})(e)&&(n=S(t,e,n))}),r&&n.meta&&(n.meta.forEach(e=>w(t,e)),n.meta=n.meta.filter((t,e,n)=>!t.hasOwnProperty(u)||e===K(n,e=>e[u]===t[u]))),n}function E(t={},e,n=[]){let i=S(t,e,y);i.title&&(i.titleChunk=i.title),i.titleTemplate&&"%s"!==i.titleTemplate&&w({component:e,contentKeyName:"title"},i,i.titleTemplate,i.titleChunk||""),i.base&&(i.base=Object.keys(i.base).length?[i.base]:[]);const a={doEscape:t=>n.reduce((t,[e,n])=>t.replace(e,n),t)};return g.forEach((t,e)=>{if(0===e)u(i,t);else if(1===e)for(const e in i[t])u(i[t],e);a[t]=i[t]}),i=function t(e,n,i){const{tagIDKeyName:a}=n,{doEscape:s=(t=>t),escapeKeys:u}=i,c={};for(const l in e){const d=e[l];if(z(b,l)){c[l]=d;continue}let[f]=g;if(i[f]&&z(i[f],l)){c[l]=d;continue}const h=e[a];if(h&&(f=g[1],i[f]&&i[f][h]&&z(i[f][h],l)))c[l]=d;else if("string"==typeof d?c[l]=s(d):o(d)?c[l]=d.map(e=>r(e)?t(e,n,{...i,escapeKeys:!0}):s(e)):r(d)?c[l]=t(d,n,{...i,escapeKeys:!0}):c[l]=d,u){const t=s(l);l!==t&&(c[t]=c[l],delete c[l])}}return c}(i,t,a)}function j(t,e){return t[e]||(t[e]=document.getElementsByTagName(e)[0]),t[e]}function x({body:t,pbody:e}){return t?"body":e?"pbody":"head"}function P(t,{appId:e,attribute:n,type:o,tagIDKeyName:i},a={}){const r=[`${o}[${n}="${e}"]`,`${o}[data-${i}]`].map(t=>{for(const e in a){const n=a[e];t+=`[data-${e}${n&&!0!==n?`="${n}"`:""}]`}return t});return k(t.querySelectorAll(r.join(", ")))}const C=[];function L(t,e){1===arguments.length&&(e=t,t=""),C.push([t,e])}function H({tagIDKeyName:t},e,n,o){let i=!1;for(const o of n)o[t]&&o.callback&&(i=!0,L(`${e}[data-${t}="${o[t]}"]`,o.callback));return o&&i?B():i}function B(){!function(t=document){return"complete"===t.readyState}()?document.onreadystatechange=()=>{q()}:q()}function q(t){for(const[e,n]of C){const o=`${e}[onload="this.__vm_l=1"]`;let i=[];t||(i=k(document.querySelectorAll(o))),t&&t.matches(o)&&(i=[t]);for(const t of i){if(t.__vm_cb)continue;const e=()=>{t.__vm_cb=!0,t.removeAttribute("onload"),n(t)};t.__vm_l?e():t.__vm_ev||(t.__vm_ev=!0,t.addEventListener("load",e))}}}function V({attribute:t}={},e,n){const i=n.getAttribute(t),a=i?i.split(","):[],r=k(a),s=[];for(const t in e)if(e.hasOwnProperty(t)){const i=z(N,t)?"":o(e[t])?e[t].join(" "):e[t];n.setAttribute(t,i||""),z(a,t)||a.push(t),s.push(r.indexOf(t))}const u=r.filter((t,e)=>!z(s,e)).reduce((t,e)=>(n.removeAttribute(e),t+1),0);a.length===u?n.removeAttribute(t):n.setAttribute(t,a.sort().join(","))}function W(t,e={},n,o,i,a){const{attribute:r,tagIDKeyName:s}=e,u=[s,...T],c=[],l={appId:t,attribute:r,type:n,tagIDKeyName:s},d={head:P(i,l),pbody:P(a,l,{pbody:!0}),body:P(a,l,{body:!0})};if(o.length>1){const t=[];o=o.filter(e=>{const n=JSON.stringify(e),o=!z(t,n);return t.push(n),o})}if(o.length)for(const e of o){if(e.skip)continue;const o=document.createElement(n);o.setAttribute(r,t);for(const t in e){if(!e.hasOwnProperty(t))continue;if("innerHTML"===t){o.innerHTML=e.innerHTML;continue}if("json"===t){o.innerHTML=JSON.stringify(e.json);continue}if("cssText"===t){o.styleSheet?o.styleSheet.cssText=e.cssText:o.appendChild(document.createTextNode(e.cssText));continue}if("callback"===t){o.onload=()=>e[t](o);continue}const n=z(u,t)?`data-${t}`:t,i=z(N,t);if(i&&!e[t])continue;const a=i?"":e[t];o.setAttribute(n,a)}const i=d[x(e)];let a;i.some((t,e)=>(a=e,o.isEqualNode(t)))&&(a||0===a)?i.splice(a,1):c.push(o)}let f=[];for(const t of Object.values(d))f=[...f,...t];for(const t of f)t.parentNode.removeChild(t);for(const t of c)t.hasAttribute("data-body")?a.appendChild(t):t.hasAttribute("data-pbody")?a.insertBefore(t,a.firstChild):i.appendChild(t);return{oldTags:f,newTags:c}}function G(t={}){return function(){const e=E(t,this.$root,D),n=function(t,e={},n){const{ssrAttribute:i,ssrAppId:a}=e,r={},s=j(r,"html");if(t===a&&s.hasAttribute(i)){s.removeAttribute(i);let t=!1;for(const o of M)n[o]&&H(e,o,n[o])&&(t=!0);return t&&B(),!1}const u={},c={};for(const i in n){if(z(b,i))continue;if("title"===i){((l=n.title)||""===l)&&(document.title=l);continue}if(z(_,i)){const t=i.substr(0,4);V(e,n[i],j(r,t));continue}if(!o(n[i]))continue;const{oldTags:a,newTags:s}=W(t,e,i,n[i],j(r,"head"),j(r,"body"));s.length&&(u[i]=s,c[i]=a)}var l;return{addedTags:u,removedTags:c}}(this.$root._vueMeta.appId,t,e);return n&&s(e.changed)&&e.changed(e,n.addedTags,n.removedTags),{vm:this,metaInfo:e,tags:n}}}function J(t,e={}){t.__vuemeta_installed||(t.__vuemeta_installed=!0,e=function(t){t=a(t)?t:{};for(const e in $)t[e]||(t[e]=$[e]);return t}(e),t.prototype.$meta=function(t={}){const e=G(t),n=()=>{};return function(){return this.$root._vueMeta?{getOptions:()=>(function(t){const e={};for(const n in t)e[n]=t[n];return e})(t),refresh:e.bind(this),inject:n,pause:I.bind(this),resume:A.bind(this)}:{getOptions:m,refresh:m,inject:m,pause:m,resume:m}}}(e),t.mixin(function(t,e){const o=["activated","deactivated","beforeMount"];return{beforeCreate(){if(Object.defineProperty(this,"_hasMetaInfo",{configurable:!0,get(){return t.config.devtools&&!this.$root._vueMeta.hasMetaInfoDeprecationWarningShown&&(p("VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead"),this.$root._vueMeta.hasMetaInfoDeprecationWarningShown=!0),l(this)}}),!i(this.$options[e.keyName])&&null!==this.$options[e.keyName]){if(this.$root._vueMeta||(this.$root._vueMeta={appId:v},v++),!this._vueMeta){this._vueMeta=!0;let t=this.$parent;for(;t&&t!==this.$root;)i(t._vueMeta)&&(t._vueMeta=!1),t=t.$parent}s(this.$options[e.keyName])&&(this.$options.computed||(this.$options.computed={}),this.$options.computed.$metaInfo=this.$options[e.keyName],this.$isServer||c(this.$options,"created",()=>{this.$watch("$metaInfo",function(){n(this,"watcher")})})),i(this.$root._vueMeta.initialized)&&(this.$root._vueMeta.initialized=this.$isServer,this.$root._vueMeta.initialized||(c(this.$options,"beforeMount",()=>{this.$root.$el&&this.$root.$el.hasAttribute&&this.$root.$el.hasAttribute("data-server-rendered")&&(this.$root._vueMeta.appId=e.ssrAppId)}),c(this.$options,"mounted",()=>{this.$root._vueMeta.initialized||(this.$root._vueMeta.initializing=!0,this.$nextTick(function(){const{tags:t,metaInfo:o}=this.$root.$meta().refresh();!1===t&&null===this.$root._vueMeta.initialized&&this.$nextTick(()=>n(this,"initializing")),this.$root._vueMeta.initialized=!0,delete this.$root._vueMeta.initializing,!e.refreshOnceOnNavigation&&o.afterNavigation&&d(this)}))}),e.refreshOnceOnNavigation&&d(this))),this.$isServer||(o.forEach(t=>{c(this.$options,t,()=>n(this,t))}),c(this.$options,"destroyed",()=>{const t=setInterval(()=>{this.$el&&null!==this.$el.offsetParent||(clearInterval(t),this.$parent&&n(this,"destroyed"))},50)}))}}}}(t,e)))}i(window)||i(window.Vue)||J(window.Vue);var F={version:"2.1.0",install:J,hasMetaInfo:l};export default F; +import t from"deepmerge";var e=null;function n(t,n){t.$root._vueMeta.initialized||!t.$root._vueMeta.initializing&&"watcher"!==n||(t.$root._vueMeta.initialized=null),t.$root._vueMeta.initialized&&!t.$root._vueMeta.paused&&function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10;clearTimeout(e),e=setTimeout(function(){t()},n)}(function(){return t.$meta().refresh()})}function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}function a(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?i(n,!0).forEach(function(e){o(t,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):i(n).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))})}return t}function u(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=[],r=!0,o=!1,i=void 0;try{for(var a,u=t[Symbol.iterator]();!(r=(a=u.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){o=!0,i=t}finally{try{r||null==u.return||u.return()}finally{if(o)throw i}}return n}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function c(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function l(t){return Array.isArray(t)}function s(t){return void 0===t}function f(t){return"object"===r(t)}function d(t){return"object"===r(t)&&null!==t}function v(t){return"function"==typeof t}function h(t,e){return e&&f(t)?(l(t[e])||(t[e]=[]),t):l(t)?t:[]}function p(t,e,n){h(t,e),t[e].push(n)}function m(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this;return t&&(!0===t._vueMeta||f(t._vueMeta))}function y(t){if(!t.$root._vueMeta.navGuards&&t.$root.$router){t.$root._vueMeta.navGuards=!0;var e=t.$root.$router,n=t.$root.$meta();e.beforeEach(function(t,e,r){n.pause(),r()}),e.afterEach(function(){var t=n.resume().metaInfo;t&&t.afterNavigation&&v(t.afterNavigation)&&t.afterNavigation(t)})}}var g=function(){try{return!s(window)}catch(t){return!1}}()?window:global,b=g.console=g.console||{};function $(){b&&b.warn&&b.warn.apply(b,arguments)}var _=function(){return $("This vue app/component has no vue-meta configuration")},M=1;var w={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},T={keyName:"metaInfo",attribute:"data-vue-meta",ssrAttribute:"data-vue-meta-server-rendered",tagIDKeyName:"vmid",contentKeyName:"content",metaTemplateKeyName:"template",ssrAppId:"ssr"},N=["titleChunk","titleTemplate","changed","__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],A=["__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],O=["htmlAttrs","headAttrs","bodyAttrs"],I=["link","style","script"],S=["body","pbody"],j=["allowfullscreen","amp","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"];function D(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return this.$root._vueMeta.paused=!0,function(){return K(t)}}function K(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];if(this.$root._vueMeta.paused=!1,t)return this.$root.$meta().refresh()}function k(t,e,n,r){var o=t.component,i=t.metaTemplateKeyName,a=t.contentKeyName;return s(n)&&(n=e[i],delete e[i]),!!n&&(s(r)&&(r=e[a]),e[a]=v(n)?n.call(o,r):n.replace(/%s/g,r),!0)}function z(t,e){return t.findIndex(e,arguments[2])}function P(t){return Array.from(t)}function E(t,e){return t.includes(e)}var x=[[/&/g,"&"],[/</g,"<"],[/>/g,">"],[/"/g,'"'],[/'/g,"'"]];function C(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.hasOwnProperty("title")&&void 0===n.title&&delete n.title,O.forEach(function(t){if(n[t])for(var e in n[t])n[t].hasOwnProperty(e)&&void 0===n[t][e]&&(E(j,e)&&$("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),delete n[t][e])}),t(e,n,{arrayMerge:function(t,e){return function(t,e,n){var r=t.component,o=t.tagIDKeyName,i=t.metaTemplateKeyName,a=t.contentKeyName,u=[];return e.forEach(function(t,e){if(t[o]){var c=z(n,function(e){return e[o]===t[o]}),l=n[c];if(-1!==c){if(l.hasOwnProperty(a)&&void 0===l[a]||l.hasOwnProperty("innerHTML")&&void 0===l.innerHTML)return u.push(t),void n.splice(c,1);if(null!==l[a]&&null!==l.innerHTML){var s=t[i];s&&(l[i]?l[a]||k({component:r,metaTemplateKeyName:i,contentKeyName:a},l,void 0,t[a]):k({component:r,metaTemplateKeyName:i,contentKeyName:a},l,s))}else n.splice(c,1)}else u.push(t)}else u.push(t)}),u.concat(n)}(r,t,e)}})}function L(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=t.keyName,o=t.metaTemplateKeyName,i=t.tagIDKeyName,a=e.$options,u=e.$children;if(e._inactive)return n;if(a[r]){var c=a[r];if(v(c)&&(c=c.call(e)),!f(c))return n;n=C(n,c,t)}return u.length&&u.forEach(function(e){(function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this;return t&&!s(t._vueMeta)})(e)&&(n=L(t,e,n))}),o&&n.meta&&(n.meta.forEach(function(e){return k(t,e)}),n.meta=n.meta.filter(function(t,e,n){return!t.hasOwnProperty(i)||e===z(n,function(e){return e[i]===t[i]})})),n}function H(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=L(t,e,w);r.title&&(r.titleChunk=r.title),r.titleTemplate&&"%s"!==r.titleTemplate&&k({component:e,contentKeyName:"title"},r,r.titleTemplate,r.titleChunk||""),r.base&&(r.base=Object.keys(r.base).length?[r.base]:[]);var o={doEscape:function(t){return n.reduce(function(t,e){var n=u(e,2),r=n[0],o=n[1];return t.replace(r,o)},t)}};return A.forEach(function(t,e){if(0===e)h(r,t);else if(1===e)for(var n in r[t])h(r[t],n);o[t]=r[t]}),r=function t(e,n,r){var o=n.tagIDKeyName,i=r.doEscape,c=void 0===i?function(t){return t}:i,s=r.escapeKeys,f={};for(var v in e){var h=e[v];if(E(N,v))f[v]=h;else{var p=u(A,1)[0];if(r[p]&&E(r[p],v))f[v]=h;else{var m=e[o];if(m&&(p=A[1],r[p]&&r[p][m]&&E(r[p][m],v)))f[v]=h;else if("string"==typeof h?f[v]=c(h):l(h)?f[v]=h.map(function(e){return d(e)?t(e,n,a({},r,{escapeKeys:!0})):c(e)}):d(h)?f[v]=t(h,n,a({},r,{escapeKeys:!0})):f[v]=h,s){var y=c(v);v!==y&&(f[y]=f[v],delete f[v])}}}}return f}(r,t,o)}function B(t,e){return t[e]||(t[e]=document.getElementsByTagName(e)[0]),t[e]}function q(t,e){var n=e.appId,r=e.attribute,o=e.type,i=e.tagIDKeyName,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},u=["".concat(o,"[").concat(r,'="').concat(n,'"]'),"".concat(o,"[data-").concat(i,"]")].map(function(t){for(var e in a){var n=a[e],r=n&&!0!==n?'="'.concat(n,'"'):"";t+="[data-".concat(e).concat(r,"]")}return t});return P(t.querySelectorAll(u.join(", ")))}var V=[];function W(t,e){1===arguments.length&&(e=t,t=""),V.push([t,e])}function G(t,e,n,r){var o=t.tagIDKeyName,i=!1,a=!0,u=!1,c=void 0;try{for(var l,s=n[Symbol.iterator]();!(a=(l=s.next()).done);a=!0){var f=l.value;f[o]&&f.callback&&(i=!0,W("".concat(e,"[data-").concat(o,'="').concat(f[o],'"]'),f.callback))}}catch(t){u=!0,c=t}finally{try{a||null==s.return||s.return()}finally{if(u)throw c}}return r&&i?J():i}function J(){!function(){return"complete"===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:document).readyState}()?document.onreadystatechange=function(){F()}:F()}function F(t){for(var e=function(){var e=u(r[n],2),o=e[0],i=e[1],a="".concat(o,'[onload="this.__vm_l=1"]'),c=[];t||(c=P(document.querySelectorAll(a))),t&&t.matches(a)&&(c=[t]);var l=!0,s=!1,f=void 0;try{for(var d,v=function(){var t=d.value;if(t.__vm_cb)return"continue";var e=function(){t.__vm_cb=!0,t.removeAttribute("onload"),i(t)};if(t.__vm_l)return e(),"continue";t.__vm_ev||(t.__vm_ev=!0,t.addEventListener("load",e))},h=c[Symbol.iterator]();!(l=(d=h.next()).done);l=!0)v()}catch(t){s=!0,f=t}finally{try{l||null==h.return||h.return()}finally{if(s)throw f}}},n=0,r=V;n<r.length;n++)e()}function Q(){var t=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).attribute,e=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0,r=n.getAttribute(t),o=r?r.split(","):[],i=P(o),a=[];for(var u in e)if(e.hasOwnProperty(u)){var c=E(j,u)?"":l(e[u])?e[u].join(" "):e[u];n.setAttribute(u,c||""),E(o,u)||o.push(u),a.push(i.indexOf(u))}var s=i.filter(function(t,e){return!E(a,e)}).reduce(function(t,e){return n.removeAttribute(e),t+1},0);o.length===s?n.removeAttribute(t):n.setAttribute(t,o.sort().join(","))}function R(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=arguments.length>3?arguments[3]:void 0,o=arguments.length>4?arguments[4]:void 0,i=arguments.length>5?arguments[5]:void 0,a=e.attribute,u=e.tagIDKeyName,l=[u].concat(c(S)),s=[],f={appId:t,attribute:a,type:n,tagIDKeyName:u},d={head:q(o,f),pbody:q(i,f,{pbody:!0}),body:q(i,f,{body:!0})};if(r.length>1){var v=[];r=r.filter(function(t){var e=JSON.stringify(t),n=!E(v,e);return v.push(e),n})}if(r.length){var h=!0,p=!1,m=void 0;try{for(var y,g=function(){var e=y.value;if(e.skip)return"continue";var r=document.createElement(n);r.setAttribute(a,t);var o=function(t){if(!e.hasOwnProperty(t))return"continue";if("innerHTML"===t)return r.innerHTML=e.innerHTML,"continue";if("json"===t)return r.innerHTML=JSON.stringify(e.json),"continue";if("cssText"===t)return r.styleSheet?r.styleSheet.cssText=e.cssText:r.appendChild(document.createTextNode(e.cssText)),"continue";if("callback"===t)return r.onload=function(){return e[t](r)},"continue";var n=E(l,t)?"data-".concat(t):t,o=E(j,t);if(o&&!e[t])return"continue";var i=o?"":e[t];r.setAttribute(n,i)};for(var i in e)o(i);var u=d[function(t){var e=t.body,n=t.pbody;return e?"body":n?"pbody":"head"}(e)],c=void 0;u.some(function(t,e){return c=e,r.isEqualNode(t)})&&(c||0===c)?u.splice(c,1):s.push(r)},b=r[Symbol.iterator]();!(h=(y=b.next()).done);h=!0)g()}catch(t){p=!0,m=t}finally{try{h||null==b.return||b.return()}finally{if(p)throw m}}}for(var $=[],_=0,M=Object.values(d);_<M.length;_++){var w=M[_];$=[].concat(c($),c(w))}for(var T=0,N=$;T<N.length;T++){var A=N[T];A.parentNode.removeChild(A)}for(var O=0,I=s;O<I.length;O++){var D=I[O];D.hasAttribute("data-body")?i.appendChild(D):D.hasAttribute("data-pbody")?i.insertBefore(D,i.firstChild):o.appendChild(D)}return{oldTags:$,newTags:s}}function U(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return function(){var e=H(t,this.$root,x),n=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=e.ssrAttribute,o=e.ssrAppId,i={},a=B(i,"html");if(t===o&&a.hasAttribute(r)){a.removeAttribute(r);var u=!1,c=!0,s=!1,f=void 0;try{for(var d,v=I[Symbol.iterator]();!(c=(d=v.next()).done);c=!0){var h=d.value;n[h]&&G(e,h,n[h])&&(u=!0)}}catch(t){s=!0,f=t}finally{try{c||null==v.return||v.return()}finally{if(s)throw f}}return u&&J(),!1}var p,m={},y={};for(var g in n)if(!E(N,g))if("title"!==g){if(E(O,g)){var b=g.substr(0,4);Q(e,n[g],B(i,b))}else if(l(n[g])){var $=R(t,e,g,n[g],B(i,"head"),B(i,"body")),_=$.oldTags,M=$.newTags;M.length&&(m[g]=M,y[g]=_)}}else((p=n.title)||""===p)&&(document.title=p);return{addedTags:m,removedTags:y}}(this.$root._vueMeta.appId,t,e);return n&&v(e.changed)&&e.changed(e,n.addedTags,n.removedTags),{vm:this,metaInfo:e,tags:n}}}function X(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.__vuemeta_installed||(t.__vuemeta_installed=!0,e=function(t){for(var e in t=f(t)?t:{},T)t[e]||(t[e]=T[e]);return t}(e),t.prototype.$meta=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=U(t),n=function(){};return function(){return this.$root._vueMeta?{getOptions:function(){return function(t){var e={};for(var n in t)e[n]=t[n];return e}(t)},refresh:e.bind(this),inject:n,pause:D.bind(this),resume:K.bind(this)}:{getOptions:_,refresh:_,inject:_,pause:_,resume:_}}}(e),t.mixin(function(t,e){var r=["activated","deactivated","beforeMount"];return{beforeCreate:function(){var o=this;if(Object.defineProperty(this,"_hasMetaInfo",{configurable:!0,get:function(){return t.config.devtools&&!this.$root._vueMeta.hasMetaInfoDeprecationWarningShown&&($("VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead"),this.$root._vueMeta.hasMetaInfoDeprecationWarningShown=!0),m(this)}}),!s(this.$options[e.keyName])&&null!==this.$options[e.keyName]){if(this.$root._vueMeta||(this.$root._vueMeta={appId:M},M++),!this._vueMeta){this._vueMeta=!0;for(var i=this.$parent;i&&i!==this.$root;)s(i._vueMeta)&&(i._vueMeta=!1),i=i.$parent}v(this.$options[e.keyName])&&(this.$options.computed||(this.$options.computed={}),this.$options.computed.$metaInfo=this.$options[e.keyName],this.$isServer||p(this.$options,"created",function(){o.$watch("$metaInfo",function(){n(this,"watcher")})})),s(this.$root._vueMeta.initialized)&&(this.$root._vueMeta.initialized=this.$isServer,this.$root._vueMeta.initialized||(p(this.$options,"beforeMount",function(){o.$root.$el&&o.$root.$el.hasAttribute&&o.$root.$el.hasAttribute("data-server-rendered")&&(o.$root._vueMeta.appId=e.ssrAppId)}),p(this.$options,"mounted",function(){o.$root._vueMeta.initialized||(o.$root._vueMeta.initializing=!0,o.$nextTick(function(){var t=this,r=this.$root.$meta().refresh(),o=r.tags,i=r.metaInfo;!1===o&&null===this.$root._vueMeta.initialized&&this.$nextTick(function(){return n(t,"initializing")}),this.$root._vueMeta.initialized=!0,delete this.$root._vueMeta.initializing,!e.refreshOnceOnNavigation&&i.afterNavigation&&y(this)}))}),e.refreshOnceOnNavigation&&y(this))),this.$isServer||(r.forEach(function(t){p(o.$options,t,function(){return n(o,t)})}),p(this.$options,"destroyed",function(){var t=setInterval(function(){o.$el&&null!==o.$el.offsetParent||(clearInterval(t),o.$parent&&n(o,"destroyed"))},50)}))}}}}(t,e)))}s(window)||s(window.Vue)||X(window.Vue);var Y={version:"2.1.1",install:X,hasMetaInfo:m};export default Y; diff --git a/dist/vue-meta.esm.js b/dist/vue-meta.esm.js index c19ec99..dd6884f 100644 --- a/dist/vue-meta.esm.js +++ b/dist/vue-meta.esm.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.1.0 + * vue-meta v2.1.1 * (c) 2019 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -9,10 +9,10 @@ import deepmerge from 'deepmerge'; -var version = "2.1.0"; +var version = "2.1.1"; // store an id to keep track of DOM updates -let batchId = null; +var batchId = null; function triggerUpdate(vm, hookName) { // if an update was triggered during initialization or when an update was triggered by the // metaInfo watcher, set initialized to null @@ -23,7 +23,9 @@ function triggerUpdate(vm, hookName) { if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) { // batch potential DOM updates to prevent extraneous re-rendering - batchUpdate(() => vm.$meta().refresh()); + batchUpdate(function () { + return vm.$meta().refresh(); + }); } } /** @@ -34,14 +36,136 @@ function triggerUpdate(vm, hookName) { * @return {Number} id - a new ID */ -function batchUpdate(callback, timeout = 10) { +function batchUpdate(callback) { + var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; clearTimeout(batchId); - batchId = setTimeout(() => { + batchId = setTimeout(function () { callback(); }, timeout); return batchId; } +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + keys.push.apply(keys, symbols); + } + + return keys; +} + +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(source, true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(source).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; +} + +function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); +} + /** * checks if passed argument is an array * @param {any} arg - the object to check @@ -54,10 +178,10 @@ function isUndefined(arg) { return typeof arg === 'undefined'; } function isObject(arg) { - return typeof arg === 'object'; + return _typeof(arg) === 'object'; } function isPureObject(arg) { - return typeof arg === 'object' && arg !== null; + return _typeof(arg) === 'object' && arg !== null; } function isFunction(arg) { return typeof arg === 'function'; @@ -82,11 +206,13 @@ function ensuredPush(object, key, el) { object[key].push(el); } -function hasMetaInfo(vm = this) { +function hasMetaInfo() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; return vm && (vm._vueMeta === true || isObject(vm._vueMeta)); } // a component is in a metaInfo branch when itself has meta info or one of its (grand-)children has -function inMetaInfoBranch(vm = this) { +function inMetaInfoBranch() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; return vm && !isUndefined(vm._vueMeta); } @@ -98,16 +224,15 @@ function addNavGuards(vm) { } vm.$root._vueMeta.navGuards = true; - const $router = vm.$root.$router; - const $meta = vm.$root.$meta(); - $router.beforeEach((to, from, next) => { + var $router = vm.$root.$router; + var $meta = vm.$root.$meta(); + $router.beforeEach(function (to, from, next) { $meta.pause(); next(); }); - $router.afterEach(() => { - const { - metaInfo - } = $meta.resume(); + $router.afterEach(function () { + var _$meta$resume = $meta.resume(), + metaInfo = _$meta$resume.metaInfo; if (metaInfo && metaInfo.afterNavigation && isFunction(metaInfo.afterNavigation)) { metaInfo.afterNavigation(metaInfo); @@ -122,31 +247,32 @@ function hasGlobalWindowFn() { return false; } } -const hasGlobalWindow = hasGlobalWindowFn(); +var hasGlobalWindow = hasGlobalWindowFn(); -const _global = hasGlobalWindow ? window : global; +var _global = hasGlobalWindow ? window : global; -const console = _global.console = _global.console || {}; -function warn(...args) { +var console = _global.console = _global.console || {}; +function warn() { /* istanbul ignore next */ if (!console || !console.warn) { return; } - console.warn(...args); + console.warn.apply(console, arguments); } -let appId = 1; +var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates return { - beforeCreate() { + beforeCreate: function beforeCreate() { + var _this = this; + Object.defineProperty(this, '_hasMetaInfo', { configurable: true, - - get() { + get: function get() { // Show deprecation warning once when devtools enabled if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) { warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead'); @@ -155,7 +281,6 @@ function createMixin(Vue, options) { return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo // _vnode is used to know that it's attached to a real component // useful if we use some mixin to add some meta tags (like nuxt-i18n) @@ -163,7 +288,7 @@ function createMixin(Vue, options) { if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) { if (!this.$root._vueMeta) { this.$root._vueMeta = { - appId + appId: appId }; appId++; } // to speed up updates we keep track of branches which have a component with vue-meta info defined @@ -172,7 +297,7 @@ function createMixin(Vue, options) { if (!this._vueMeta) { this._vueMeta = true; - let p = this.$parent; + var p = this.$parent; while (p && p !== this.$root) { if (isUndefined(p._vueMeta)) { @@ -196,8 +321,8 @@ function createMixin(Vue, options) { // 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) - ensuredPush(this.$options, 'created', () => { - this.$watch('$metaInfo', function () { + ensuredPush(this.$options, 'created', function () { + _this.$watch('$metaInfo', function () { triggerUpdate(this, 'watcher'); }); }); @@ -212,33 +337,37 @@ function createMixin(Vue, options) { this.$root._vueMeta.initialized = this.$isServer; if (!this.$root._vueMeta.initialized) { - ensuredPush(this.$options, 'beforeMount', () => { + ensuredPush(this.$options, 'beforeMount', function () { // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if (this.$root.$el && this.$root.$el.hasAttribute && this.$root.$el.hasAttribute('data-server-rendered')) { - this.$root._vueMeta.appId = options.ssrAppId; + if (_this.$root.$el && _this.$root.$el.hasAttribute && _this.$root.$el.hasAttribute('data-server-rendered')) { + _this.$root._vueMeta.appId = options.ssrAppId; } }); // we use the mounted hook here as on page load - ensuredPush(this.$options, 'mounted', () => { - if (!this.$root._vueMeta.initialized) { + ensuredPush(this.$options, 'mounted', function () { + if (!_this.$root._vueMeta.initialized) { // used in triggerUpdate to check if a change was triggered // during initialization - this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded + _this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded - this.$nextTick(function () { - const { - tags, - metaInfo - } = this.$root.$meta().refresh(); // After ssr hydration (identifier by tags === false) check + _this.$nextTick(function () { + var _this2 = this; + + var _this$$root$$meta$ref = this.$root.$meta().refresh(), + tags = _this$$root$$meta$ref.tags, + metaInfo = _this$$root$$meta$ref.metaInfo; // After ssr hydration (identifier by tags === false) check // if initialized was set to null in triggerUpdate. That'd mean // that during initilazation changes where triggered which need // to be applied OR a metaInfo watcher was triggered before the // current hook was called // (during initialization all changes are blocked) + if (tags === false && this.$root._vueMeta.initialized === null) { - this.$nextTick(() => triggerUpdate(this, 'initializing')); + this.$nextTick(function () { + return triggerUpdate(_this2, 'initializing'); + }); } this.$root._vueMeta.initialized = true; @@ -261,32 +390,33 @@ function createMixin(Vue, options) { if (!this.$isServer) { // no need to add this hooks on server side - updateOnLifecycleHook.forEach(lifecycleHook => { - ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook)); + updateOnLifecycleHook.forEach(function (lifecycleHook) { + ensuredPush(_this.$options, lifecycleHook, function () { + return triggerUpdate(_this, lifecycleHook); + }); }); // re-render meta data when returning from a child component to parent - ensuredPush(this.$options, 'destroyed', () => { + ensuredPush(this.$options, 'destroyed', function () { // Wait that element is hidden before refreshing meta tags (to support animations) - const interval = setInterval(() => { - if (this.$el && this.$el.offsetParent !== null) { + var interval = setInterval(function () { + if (_this.$el && _this.$el.offsetParent !== null) { /* istanbul ignore next line */ return; } clearInterval(interval); - if (!this.$parent) { + if (!_this.$parent) { /* istanbul ignore next line */ return; } - triggerUpdate(this, 'destroyed'); + triggerUpdate(_this, 'destroyed'); }, 50); }); } } } - }; } @@ -294,7 +424,7 @@ function createMixin(Vue, options) { * These are constant variables used throughout the application. */ // set some sane defaults -const defaultInfo = { +var defaultInfo = { title: undefined, titleChunk: '', titleTemplate: '%s', @@ -312,58 +442,58 @@ const defaultInfo = { // gets converted to the various meta tags & attributes for the page. }; -const keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should +var keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should // manage and which it should ignore. -const attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` +var attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` // that the server has already generated the meta tags for the initial render. -const ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) +var ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) // an item in a tag list. For example, if you have two `meta` tag list items // that both have `vmid` of "description", then vue-meta will overwrite the // shallowest one with the deepest one. -const tagIDKeyName = 'vmid'; // This is the key name for possible meta templates +var tagIDKeyName = 'vmid'; // This is the key name for possible meta templates -const metaTemplateKeyName = 'template'; // This is the key name for the content-holding property +var metaTemplateKeyName = 'template'; // This is the key name for the content-holding property -const contentKeyName = 'content'; // The id used for the ssr app +var contentKeyName = 'content'; // The id used for the ssr app -const ssrAppId = 'ssr'; -const defaultOptions = { - keyName, - attribute, - ssrAttribute, - tagIDKeyName, - contentKeyName, - metaTemplateKeyName, - ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) +var ssrAppId = 'ssr'; +var defaultOptions = { + keyName: keyName, + attribute: attribute, + ssrAttribute: ssrAttribute, + tagIDKeyName: tagIDKeyName, + contentKeyName: contentKeyName, + metaTemplateKeyName: metaTemplateKeyName, + ssrAppId: ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) }; -const metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping +var metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping -const disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags +var disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags -const metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event +var metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event -const tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) +var tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) // see: https://www.w3.org/TR/html52/document-metadata.html -const tagsWithoutEndTag = ['base', 'meta', 'link']; // HTML elements which can have inner content (shortened to our needs) +var tagsWithoutEndTag = ['base', 'meta', 'link']; // HTML elements which can have inner content (shortened to our needs) -const tagsWithInnerContent = ['noscript', 'script', 'style']; // Attributes which are inserted as childNodes instead of HTMLAttribute +var tagsWithInnerContent = ['noscript', 'script', 'style']; // Attributes which are inserted as childNodes instead of HTMLAttribute -const tagAttributeAsInnerContent = ['innerHTML', 'cssText', 'json']; // Attributes which should be added with data- prefix +var tagAttributeAsInnerContent = ['innerHTML', 'cssText', 'json']; // Attributes which should be added with data- prefix -const commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 +var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -const booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; +var booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; function setOptions(options) { // combine options options = isObject(options) ? options : {}; - for (const key in defaultOptions) { + for (var key in defaultOptions) { if (!options[key]) { options[key] = defaultOptions[key]; } @@ -372,20 +502,24 @@ function setOptions(options) { return options; } function getOptions(options) { - const optionsCopy = {}; + var optionsCopy = {}; - for (const key in options) { + for (var key in options) { optionsCopy[key] = options[key]; } return optionsCopy; } -function pause(refresh = true) { +function pause() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = true; - return () => resume(refresh); + return function () { + return resume(refresh); + }; } -function resume(refresh = true) { +function resume() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = false; if (refresh) { @@ -393,11 +527,11 @@ function resume(refresh = true) { } } -function applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName -}, headObject, template, chunk) { +function applyTemplate(_ref, headObject, template, chunk) { + var component = _ref.component, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; + if (isUndefined(template)) { template = headObject[metaTemplateKeyName]; delete headObject[metaTemplateKeyName]; @@ -425,62 +559,40 @@ function applyTemplate({ * files in server/ still use normal js function */ function findIndex(array, predicate) { - if ( !Array.prototype.findIndex) { - // idx needs to be a Number, for..in returns string - for (let idx = 0; idx < array.length; idx++) { - if (predicate.call(arguments[2], array[idx], idx, array)) { - return idx; - } - } - - return -1; - } return array.findIndex(predicate, arguments[2]); } function toArray(arg) { - if ( !Array.from) { - return Array.prototype.slice.call(arg); - } return Array.from(arg); } function includes(array, value) { - if ( !Array.prototype.includes) { - for (const idx in array) { - if (array[idx] === value) { - return true; - } - } - - return false; - } return array.includes(value); } -const serverSequences = [[/&/g, '&'], [/</g, '<'], [/>/g, '>'], [/"/g, '"'], [/'/g, ''']]; -const clientSequences = [[/&/g, '\u0026'], [/</g, '\u003C'], [/>/g, '\u003E'], [/"/g, '\u0022'], [/'/g, '\u0027']]; // sanitizes potentially dangerous characters +var serverSequences = [[/&/g, '&'], [/</g, '<'], [/>/g, '>'], [/"/g, '"'], [/'/g, ''']]; +var clientSequences = [[/&/g, "&"], [/</g, "<"], [/>/g, ">"], [/"/g, "\""], [/'/g, "'"]]; // sanitizes potentially dangerous characters function escape(info, options, escapeOptions) { - const { - tagIDKeyName - } = options; - const { - doEscape = v => v, - escapeKeys - } = escapeOptions; - const escaped = {}; + var tagIDKeyName = options.tagIDKeyName; + var _escapeOptions$doEsca = escapeOptions.doEscape, + doEscape = _escapeOptions$doEsca === void 0 ? function (v) { + return v; + } : _escapeOptions$doEsca, + escapeKeys = escapeOptions.escapeKeys; + var escaped = {}; - for (const key in info) { - const value = info[key]; // no need to escape configuration options + for (var key in info) { + var value = info[key]; // no need to escape configuration options if (includes(metaInfoOptionKeys, key)) { escaped[key] = value; continue; } - let [disableKey] = disableOptionKeys; + var _disableOptionKeys = _slicedToArray(disableOptionKeys, 1), + disableKey = _disableOptionKeys[0]; if (escapeOptions[disableKey] && includes(escapeOptions[disableKey], key)) { // this info[key] doesnt need to escaped if the option is listed in __dangerouslyDisableSanitizers @@ -488,7 +600,7 @@ function escape(info, options, escapeOptions) { continue; } - const tagId = info[tagIDKeyName]; + var tagId = info[tagIDKeyName]; if (tagId) { disableKey = disableOptionKeys[1]; // keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped @@ -502,25 +614,25 @@ function escape(info, options, escapeOptions) { if (isString(value)) { escaped[key] = doEscape(value); } else if (isArray(value)) { - escaped[key] = value.map(v => { + escaped[key] = value.map(function (v) { if (isPureObject(v)) { - return escape(v, options, { ...escapeOptions, + return escape(v, options, _objectSpread2({}, escapeOptions, { escapeKeys: true - }); + })); } return doEscape(v); }); } else if (isPureObject(value)) { - escaped[key] = escape(value, options, { ...escapeOptions, + escaped[key] = escape(value, options, _objectSpread2({}, escapeOptions, { escapeKeys: true - }); + })); } else { escaped[key] = value; } if (escapeKeys) { - const escapedKey = doEscape(key); + var escapedKey = doEscape(key); if (key !== escapedKey) { escaped[escapedKey] = escaped[key]; @@ -532,25 +644,26 @@ function escape(info, options, escapeOptions) { return escaped; } -function arrayMerge({ - component, - tagIDKeyName, - metaTemplateKeyName, - contentKeyName -}, target, source) { +function _arrayMerge(_ref, target, source) { + var component = _ref.component, + tagIDKeyName = _ref.tagIDKeyName, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; // we concat the arrays without merging objects contained in, // but we check for a `vmid` property on each object in the array // using an O(1) lookup associative array exploit - const destination = []; - target.forEach((targetItem, targetIndex) => { + var destination = []; + target.forEach(function (targetItem, targetIndex) { // no tagID so no need to check for duplicity if (!targetItem[tagIDKeyName]) { destination.push(targetItem); return; } - const sourceIndex = findIndex(source, item => item[tagIDKeyName] === targetItem[tagIDKeyName]); - const sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem + var sourceIndex = findIndex(source, function (item) { + return item[tagIDKeyName] === targetItem[tagIDKeyName]; + }); + var sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem if (sourceIndex === -1) { destination.push(targetItem); @@ -576,33 +689,35 @@ function arrayMerge({ } // now we only need to check if the target has a template to combine it with the source - const targetTemplate = targetItem[metaTemplateKeyName]; + var targetTemplate = targetItem[metaTemplateKeyName]; if (!targetTemplate) { return; } - const sourceTemplate = sourceItem[metaTemplateKeyName]; + var sourceTemplate = sourceItem[metaTemplateKeyName]; if (!sourceTemplate) { // use parent template and child content applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName }, sourceItem, targetTemplate); } else if (!sourceItem[contentKeyName]) { // use child template and parent content applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName }, sourceItem, undefined, targetItem[contentKeyName]); } }); return destination.concat(source); } -function merge(target, source, options = {}) { +function merge(target, source) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // remove properties explicitly set to false so child components can // optionally _not_ overwrite the parents content // (for array properties this is checked in arrayMerge) @@ -610,12 +725,12 @@ function merge(target, source, options = {}) { delete source.title; } - metaInfoAttributeKeys.forEach(attrKey => { + metaInfoAttributeKeys.forEach(function (attrKey) { if (!source[attrKey]) { return; } - for (const key in source[attrKey]) { + for (var key in source[attrKey]) { if (source[attrKey].hasOwnProperty(key) && source[attrKey][key] === undefined) { if (includes(booleanHtmlAttributes, key)) { warn('VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details'); @@ -626,7 +741,9 @@ function merge(target, source, options = {}) { } }); return deepmerge(target, source, { - arrayMerge: (t, s) => arrayMerge(options, t, s) + arrayMerge: function arrayMerge(t, s) { + return _arrayMerge(options, t, s); + } }); } @@ -645,16 +762,15 @@ function merge(target, source, options = {}) { * @return {Object} result - final aggregated result */ -function getComponentOption(options = {}, component, result = {}) { - const { - keyName, - metaTemplateKeyName, - tagIDKeyName - } = options; - const { - $options, - $children - } = component; +function getComponentOption() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var keyName = options.keyName, + metaTemplateKeyName = options.metaTemplateKeyName, + tagIDKeyName = options.tagIDKeyName; + var $options = component.$options, + $children = component.$children; if (component._inactive) { return result; @@ -662,7 +778,7 @@ function getComponentOption(options = {}, component, result = {}) { if ($options[keyName]) { - let data = $options[keyName]; // if option is a function, replace it with it's result + var data = $options[keyName]; // if option is a function, replace it with it's result if (isFunction(data)) { data = data.call(component); @@ -679,7 +795,7 @@ function getComponentOption(options = {}, component, result = {}) { if ($children.length) { - $children.forEach(childComponent => { + $children.forEach(function (childComponent) { // check if the childComponent is in a branch // return otherwise so we dont walk all component branches unnecessarily if (!inMetaInfoBranch(childComponent)) { @@ -692,12 +808,16 @@ function getComponentOption(options = {}, component, result = {}) { if (metaTemplateKeyName && result.meta) { // apply templates if needed - result.meta.forEach(metaObject => applyTemplate(options, metaObject)); // remove meta items with duplicate vmid's + result.meta.forEach(function (metaObject) { + return applyTemplate(options, metaObject); + }); // remove meta items with duplicate vmid's - result.meta = result.meta.filter((metaItem, index, arr) => { + result.meta = result.meta.filter(function (metaItem, index, arr) { return (// keep meta item if it doesnt has a vmid !metaItem.hasOwnProperty(tagIDKeyName) || // or if it's the first item in the array with this vmid - index === findIndex(arr, item => item[tagIDKeyName] === metaItem[tagIDKeyName]) + index === findIndex(arr, function (item) { + return item[tagIDKeyName] === metaItem[tagIDKeyName]; + }) ); }); } @@ -713,9 +833,12 @@ function getComponentOption(options = {}, component, result = {}) { * @return {Object} - returned meta info */ -function getMetaInfo(options = {}, component, escapeSequences = []) { +function getMetaInfo() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var escapeSequences = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; // collect & aggregate all metaInfo $options - let info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta + var info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta // backup the title chunk in case user wants access to it if (info.title) { @@ -725,7 +848,7 @@ function getMetaInfo(options = {}, component, escapeSequences = []) { if (info.titleTemplate && info.titleTemplate !== '%s') { applyTemplate({ - component, + component: component, contentKeyName: 'title' }, info, info.titleTemplate, info.titleChunk || ''); } // convert base tag to an array so it can be handled the same way @@ -736,14 +859,22 @@ 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) + var escapeOptions = { + doEscape: function doEscape(value) { + return escapeSequences.reduce(function (val, _ref) { + var _ref2 = _slicedToArray(_ref, 2), + v = _ref2[0], + r = _ref2[1]; + + return val.replace(v, r); + }, value); + } }; - disableOptionKeys.forEach((disableKey, index) => { + disableOptionKeys.forEach(function (disableKey, index) { if (index === 0) { ensureIsArray(info, disableKey); } else if (index === 1) { - for (const key in info[disableKey]) { + for (var key in info[disableKey]) { ensureIsArray(info[disableKey], key); } } @@ -762,23 +893,22 @@ function getTag(tags, tag) { return tags[tag]; } -function getElementsKey({ - body, - pbody -}) { +function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; return body ? 'body' : pbody ? 'pbody' : 'head'; } -function queryElements(parentNode, { - appId, - attribute, - type, - tagIDKeyName -}, attributes = {}) { - const queries = [`${type}[${attribute}="${appId}"]`, `${type}[data-${tagIDKeyName}]`].map(query => { - for (const key in attributes) { - const val = attributes[key]; - const attributeValue = val && val !== true ? `="${val}"` : ''; - query += `[data-${key}${attributeValue}]`; +function queryElements(parentNode, _ref2) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var queries = ["".concat(type, "[").concat(attribute, "=\"").concat(appId, "\"]"), "".concat(type, "[data-").concat(tagIDKeyName, "]")].map(function (query) { + for (var key in attributes) { + var val = attributes[key]; + var attributeValue = val && val !== true ? "=\"".concat(val, "\"") : ''; + query += "[data-".concat(key).concat(attributeValue, "]"); } return query; @@ -786,8 +916,9 @@ function queryElements(parentNode, { return toArray(parentNode.querySelectorAll(queries.join(', '))); } -const callbacks = []; -function isDOMComplete(d = document) { +var callbacks = []; +function isDOMComplete() { + var d = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; return d.readyState === 'complete'; } function addCallback(query, callback) { @@ -798,18 +929,37 @@ function addCallback(query, callback) { callbacks.push([query, callback]); } -function addCallbacks({ - tagIDKeyName -}, type, tags, autoAddListeners) { - let hasAsyncCallback = false; +function addCallbacks(_ref, type, tags, autoAddListeners) { + var tagIDKeyName = _ref.tagIDKeyName; + var hasAsyncCallback = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - for (const tag of tags) { - if (!tag[tagIDKeyName] || !tag.callback) { - continue; + try { + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var tag = _step.value; + + if (!tag[tagIDKeyName] || !tag.callback) { + continue; + } + + hasAsyncCallback = true; + addCallback("".concat(type, "[data-").concat(tagIDKeyName, "=\"").concat(tag[tagIDKeyName], "\"]"), tag.callback); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } - - hasAsyncCallback = true; - addCallback(`${type}[data-${tagIDKeyName}="${tag[tagIDKeyName]}"]`, tag.callback); } if (!autoAddListeners || !hasAsyncCallback) { @@ -827,14 +977,18 @@ function addListeners() { /* istanbul ignore next */ - document.onreadystatechange = () => { + document.onreadystatechange = function () { applyCallbacks(); }; } function applyCallbacks(matchElement) { - for (const [query, callback] of callbacks) { - const selector = `${query}[onload="this.__vm_l=1"]`; - let elements = []; + var _loop = function _loop() { + var _callbacks$_i = _slicedToArray(_callbacks[_i], 2), + query = _callbacks$_i[0], + callback = _callbacks$_i[1]; + + var selector = "".concat(query, "[onload=\"this.__vm_l=1\"]"); + var elements = []; if (!matchElement) { elements = toArray(document.querySelectorAll(selector)); @@ -844,47 +998,78 @@ function applyCallbacks(matchElement) { elements = [matchElement]; } - for (const element of elements) { - /* __vm_cb: whether the load callback has been called - * __vm_l: set by onload attribute, whether the element was loaded - * __vm_ev: whether the event listener was added or not - */ - if (element.__vm_cb) { - continue; - } + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; - const onload = () => { - /* Mark that the callback for this element has already been called, - * this prevents the callback to run twice in some (rare) conditions + try { + var _loop2 = function _loop2() { + var element = _step2.value; + + /* __vm_cb: whether the load callback has been called + * __vm_l: set by onload attribute, whether the element was loaded + * __vm_ev: whether the event listener was added or not */ - element.__vm_cb = true; - /* onload needs to be removed because we only need the - * attribute after ssr and if we dont remove it the node - * will fail isEqualNode on the client + if (element.__vm_cb) { + return "continue"; + } + + var onload = function onload() { + /* Mark that the callback for this element has already been called, + * this prevents the callback to run twice in some (rare) conditions + */ + element.__vm_cb = true; + /* onload needs to be removed because we only need the + * attribute after ssr and if we dont remove it the node + * will fail isEqualNode on the client + */ + + element.removeAttribute('onload'); + callback(element); + }; + /* IE9 doesnt seem to load scripts synchronously, + * causing a script sometimes/often already to be loaded + * when we add the event listener below (thus adding an onload event + * listener has no use because it will never be triggered). + * Therefore we add the onload attribute during ssr, and + * check here if it was already loaded or not */ - element.removeAttribute('onload'); - callback(element); + + if (element.__vm_l) { + onload(); + return "continue"; + } + + if (!element.__vm_ev) { + element.__vm_ev = true; + element.addEventListener('load', onload); + } }; - /* IE9 doesnt seem to load scripts synchronously, - * causing a script sometimes/often already to be loaded - * when we add the event listener below (thus adding an onload event - * listener has no use because it will never be triggered). - * Therefore we add the onload attribute during ssr, and - * check here if it was already loaded or not - */ + for (var _iterator2 = elements[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var _ret = _loop2(); - if (element.__vm_l) { - onload(); - continue; + if (_ret === "continue") continue; } - - if (!element.__vm_ev) { - element.__vm_ev = true; - element.addEventListener('load', onload); + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } } } + }; + + for (var _i = 0, _callbacks = callbacks; _i < _callbacks.length; _i++) { + _loop(); } } @@ -895,17 +1080,20 @@ function applyCallbacks(matchElement) { * @param {HTMLElement} tag - the HTMLElement tag to update with new attrs */ -function updateAttribute({ - attribute -} = {}, attrs, tag) { - const vueMetaAttrString = tag.getAttribute(attribute); - const vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; - const toRemove = toArray(vueMetaAttrs); - const keepIndexes = []; +function updateAttribute() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute; - for (const attr in attrs) { + var attrs = arguments.length > 1 ? arguments[1] : undefined; + var tag = arguments.length > 2 ? arguments[2] : undefined; + var vueMetaAttrString = tag.getAttribute(attribute); + var vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; + var toRemove = toArray(vueMetaAttrs); + var keepIndexes = []; + + for (var attr in attrs) { if (attrs.hasOwnProperty(attr)) { - const value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; + var value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; tag.setAttribute(attr, value || ''); if (!includes(vueMetaAttrs, attr)) { @@ -917,7 +1105,9 @@ function updateAttribute({ } } - const removedAttributesCount = toRemove.filter((el, index) => !includes(keepIndexes, index)).reduce((acc, attr) => { + var removedAttributesCount = toRemove.filter(function (el, index) { + return !includes(keepIndexes, index); + }).reduce(function (acc, attr) { tag.removeAttribute(attr); return acc + 1; }, 0); @@ -951,20 +1141,23 @@ function updateTitle(title) { * @return {Object} - a representation of what tags changed */ -function updateTag(appId, options = {}, type, tags, head, body) { - const { - attribute, - tagIDKeyName - } = options; - const dataAttributes = [tagIDKeyName, ...commonDataAttributes]; - const newElements = []; - const queryOptions = { - appId, - attribute, - type, - tagIDKeyName +function updateTag(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var type = arguments.length > 2 ? arguments[2] : undefined; + var tags = arguments.length > 3 ? arguments[3] : undefined; + var head = arguments.length > 4 ? arguments[4] : undefined; + var body = arguments.length > 5 ? arguments[5] : undefined; + var attribute = options.attribute, + tagIDKeyName = options.tagIDKeyName; + var dataAttributes = [tagIDKeyName].concat(_toConsumableArray(commonDataAttributes)); + var newElements = []; + var queryOptions = { + appId: appId, + attribute: attribute, + type: type, + tagIDKeyName: tagIDKeyName }; - const currentElements = { + var currentElements = { head: queryElements(head, queryOptions), pbody: queryElements(body, queryOptions, { pbody: true @@ -978,109 +1171,148 @@ function updateTag(appId, options = {}, type, tags, head, body) { // remove duplicates that could have been found by merging tags // which include a mixin with metaInfo and that mixin is used // by multiple components on the same page - const found = []; - tags = tags.filter(x => { - const k = JSON.stringify(x); - const res = !includes(found, k); + var found = []; + tags = tags.filter(function (x) { + var k = JSON.stringify(x); + var res = !includes(found, k); found.push(k); return res; }); } if (tags.length) { - for (const tag of tags) { - if (tag.skip) { - continue; - } + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - const newElement = document.createElement(type); - newElement.setAttribute(attribute, appId); + try { + var _loop = function _loop() { + var tag = _step.value; - for (const attr in tag) { - /* istanbul ignore next */ - if (!tag.hasOwnProperty(attr)) { - continue; + if (tag.skip) { + return "continue"; } - if (attr === 'innerHTML') { - newElement.innerHTML = tag.innerHTML; - continue; - } + var newElement = document.createElement(type); + newElement.setAttribute(attribute, appId); - if (attr === 'json') { - newElement.innerHTML = JSON.stringify(tag.json); - continue; - } - - if (attr === 'cssText') { - if (newElement.styleSheet) { - /* istanbul ignore next */ - newElement.styleSheet.cssText = tag.cssText; - } else { - newElement.appendChild(document.createTextNode(tag.cssText)); + var _loop2 = function _loop2(attr) { + /* istanbul ignore next */ + if (!tag.hasOwnProperty(attr)) { + return "continue"; } - continue; + if (attr === 'innerHTML') { + newElement.innerHTML = tag.innerHTML; + return "continue"; + } + + if (attr === 'json') { + newElement.innerHTML = JSON.stringify(tag.json); + return "continue"; + } + + if (attr === 'cssText') { + if (newElement.styleSheet) { + /* istanbul ignore next */ + newElement.styleSheet.cssText = tag.cssText; + } else { + newElement.appendChild(document.createTextNode(tag.cssText)); + } + + return "continue"; + } + + if (attr === 'callback') { + newElement.onload = function () { + return tag[attr](newElement); + }; + + return "continue"; + } + + var _attr = includes(dataAttributes, attr) ? "data-".concat(attr) : attr; + + var isBooleanAttribute = includes(booleanHtmlAttributes, attr); + + if (isBooleanAttribute && !tag[attr]) { + return "continue"; + } + + var value = isBooleanAttribute ? '' : tag[attr]; + newElement.setAttribute(_attr, value); + }; + + for (var attr in tag) { + var _ret2 = _loop2(attr); + + if (_ret2 === "continue") continue; } - if (attr === 'callback') { - newElement.onload = () => tag[attr](newElement); + var oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - continue; + var indexToDelete = void 0; + var hasEqualElement = oldElements.some(function (existingTag, index) { + indexToDelete = index; + return newElement.isEqualNode(existingTag); + }); + + if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { + oldElements.splice(indexToDelete, 1); + } else { + newElements.push(newElement); } + }; - const _attr = includes(dataAttributes, attr) ? `data-${attr}` : attr; + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _ret = _loop(); - const isBooleanAttribute = includes(booleanHtmlAttributes, attr); - - if (isBooleanAttribute && !tag[attr]) { - continue; - } - - const value = isBooleanAttribute ? '' : tag[attr]; - newElement.setAttribute(_attr, value); + if (_ret === "continue") continue; } - - const oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - - let indexToDelete; - const hasEqualElement = oldElements.some((existingTag, index) => { - indexToDelete = index; - return newElement.isEqualNode(existingTag); - }); - - if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { - oldElements.splice(indexToDelete, 1); - } else { - newElements.push(newElement); + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } } - let oldElements = []; + var oldElements = []; - for (const current of Object.values(currentElements)) { - oldElements = [...oldElements, ...current]; + for (var _i = 0, _Object$values = Object.values(currentElements); _i < _Object$values.length; _i++) { + var current = _Object$values[_i]; + oldElements = [].concat(_toConsumableArray(oldElements), _toConsumableArray(current)); } // remove old elements - for (const element of oldElements) { + for (var _i2 = 0, _oldElements = oldElements; _i2 < _oldElements.length; _i2++) { + var element = _oldElements[_i2]; element.parentNode.removeChild(element); } // insert new elements - for (const element of newElements) { - if (element.hasAttribute('data-body')) { - body.appendChild(element); + for (var _i3 = 0, _newElements = newElements; _i3 < _newElements.length; _i3++) { + var _element = _newElements[_i3]; + + if (_element.hasAttribute('data-body')) { + body.appendChild(_element); continue; } - if (element.hasAttribute('data-pbody')) { - body.insertBefore(element, body.firstChild); + if (_element.hasAttribute('data-pbody')) { + body.insertBefore(_element, body.firstChild); continue; } - head.appendChild(element); + head.appendChild(_element); } return { @@ -1095,24 +1327,44 @@ function updateTag(appId, options = {}, type, tags, head, body) { * @param {Object} newInfo - the meta info to update to */ -function updateClientMetaInfo(appId, options = {}, newInfo) { - const { - ssrAttribute, - ssrAppId - } = options; // only cache tags for current update +function updateClientMetaInfo(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var newInfo = arguments.length > 2 ? arguments[2] : undefined; + var ssrAttribute = options.ssrAttribute, + ssrAppId = options.ssrAppId; // only cache tags for current update - const tags = {}; - const htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update + var tags = {}; + var htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update if (appId === ssrAppId && htmlTag.hasAttribute(ssrAttribute)) { // remove the server render attribute so we can update on (next) changes htmlTag.removeAttribute(ssrAttribute); // add load callbacks if the - let addLoadListeners = false; + var addLoadListeners = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - for (const type of tagsSupportingOnload) { - if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { - addLoadListeners = true; + try { + for (var _iterator = tagsSupportingOnload[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var type = _step.value; + + if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { + addLoadListeners = true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } @@ -1124,50 +1376,52 @@ function updateClientMetaInfo(appId, options = {}, newInfo) { } // initialize tracked changes - const addedTags = {}; - const removedTags = {}; + var addedTags = {}; + var removedTags = {}; - for (const type in newInfo) { + for (var _type in newInfo) { // ignore these - if (includes(metaInfoOptionKeys, type)) { + if (includes(metaInfoOptionKeys, _type)) { continue; } - if (type === 'title') { + if (_type === 'title') { // update the title updateTitle(newInfo.title); continue; } - if (includes(metaInfoAttributeKeys, type)) { - const tagName = type.substr(0, 4); - updateAttribute(options, newInfo[type], getTag(tags, tagName)); + if (includes(metaInfoAttributeKeys, _type)) { + var tagName = _type.substr(0, 4); + + updateAttribute(options, newInfo[_type], getTag(tags, tagName)); continue; } // tags should always be an array, ignore if it isnt - if (!isArray(newInfo[type])) { + if (!isArray(newInfo[_type])) { continue; } - const { - oldTags, - newTags - } = updateTag(appId, options, type, newInfo[type], getTag(tags, 'head'), getTag(tags, 'body')); + var _updateTag = updateTag(appId, options, _type, newInfo[_type], getTag(tags, 'head'), getTag(tags, 'body')), + oldTags = _updateTag.oldTags, + newTags = _updateTag.newTags; if (newTags.length) { - addedTags[type] = newTags; - removedTags[type] = oldTags; + addedTags[_type] = newTags; + removedTags[_type] = oldTags; } } return { - addedTags, - removedTags + addedTags: addedTags, + removedTags: removedTags }; } -function _refresh(options = {}) { +function _refresh() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** * When called, will update the current meta info with new meta info. * Useful when updating meta info as the result of an asynchronous @@ -1179,9 +1433,9 @@ function _refresh(options = {}) { * @return {Object} - new meta info */ return function refresh() { - const metaInfo = getMetaInfo(options, this.$root, clientSequences); - const appId = this.$root._vueMeta.appId; - const tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info + var metaInfo = getMetaInfo(options, this.$root, clientSequences); + var appId = this.$root._vueMeta.appId; + var tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info if (tags && isFunction(metaInfo.changed)) { metaInfo.changed(metaInfo, tags.addedTags, tags.removedTags); @@ -1189,8 +1443,8 @@ function _refresh(options = {}) { return { vm: this, - metaInfo, - tags + metaInfo: metaInfo, + tags: tags }; }; } @@ -1203,34 +1457,36 @@ function _refresh(options = {}) { * @return {Object} - the attribute generator */ -function attributeGenerator({ - attribute, - ssrAttribute -} = {}, type, data) { - return { - text(addSrrAttribute) { - let attributeStr = ''; - const watchedAttrs = []; +function attributeGenerator() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute, + ssrAttribute = _ref.ssrAttribute; - for (const attr in data) { + var type = arguments.length > 1 ? arguments[1] : undefined; + var data = arguments.length > 2 ? arguments[2] : undefined; + return { + text: function text(addSrrAttribute) { + var attributeStr = ''; + var watchedAttrs = []; + + for (var attr in data) { if (data.hasOwnProperty(attr)) { watchedAttrs.push(attr); - attributeStr += isUndefined(data[attr]) || booleanHtmlAttributes.includes(attr) ? attr : `${attr}="${isArray(data[attr]) ? data[attr].join(' ') : data[attr]}"`; + attributeStr += isUndefined(data[attr]) || booleanHtmlAttributes.includes(attr) ? attr : "".concat(attr, "=\"").concat(isArray(data[attr]) ? data[attr].join(' ') : data[attr], "\""); attributeStr += ' '; } } if (attributeStr) { - attributeStr += `${attribute}="${watchedAttrs.sort().join(',')}"`; + attributeStr += "".concat(attribute, "=\"").concat(watchedAttrs.sort().join(','), "\""); } if (type === 'htmlAttrs' && addSrrAttribute) { - return `${ssrAttribute}${attributeStr ? ' ' : ''}${attributeStr}`; + return "".concat(ssrAttribute).concat(attributeStr ? ' ' : '').concat(attributeStr); } return attributeStr; } - }; } @@ -1241,18 +1497,20 @@ function attributeGenerator({ * @param {String} data - the title text * @return {Object} - the title generator */ -function titleGenerator({ - attribute -} = {}, type, data) { +function titleGenerator() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute; + + var type = arguments.length > 1 ? arguments[1] : undefined; + var data = arguments.length > 2 ? arguments[2] : undefined; return { - text() { + text: function text() { if (!data) { return ''; } - return `<${type}>${data}</${type}>`; + return "<".concat(type, ">").concat(data, "</").concat(type, ">"); } - }; } @@ -1264,24 +1522,30 @@ function titleGenerator({ * @return {Object} - the tag generator */ -function tagGenerator({ - ssrAppId, - attribute, - tagIDKeyName -} = {}, type, tags) { - const dataAttributes = [tagIDKeyName, 'callback', ...commonDataAttributes]; +function tagGenerator() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + ssrAppId = _ref.ssrAppId, + attribute = _ref.attribute, + tagIDKeyName = _ref.tagIDKeyName; + + var type = arguments.length > 1 ? arguments[1] : undefined; + var tags = arguments.length > 2 ? arguments[2] : undefined; + var dataAttributes = [tagIDKeyName, 'callback'].concat(_toConsumableArray(commonDataAttributes)); return { - text({ - body = false, - pbody = false - } = {}) { + text: function text() { + var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref2$body = _ref2.body, + body = _ref2$body === void 0 ? false : _ref2$body, + _ref2$pbody = _ref2.pbody, + pbody = _ref2$pbody === void 0 ? false : _ref2$pbody; + // build a string containing all tags of this type - return tags.reduce((tagsStr, tag) => { + return tags.reduce(function (tagsStr, tag) { if (tag.skip) { return tagsStr; } - const tagKeys = Object.keys(tag); + var tagKeys = Object.keys(tag); if (tagKeys.length === 0) { return tagsStr; // Bail on empty tag object @@ -1291,53 +1555,52 @@ function tagGenerator({ return tagsStr; } - let attrs = tag.once ? '' : ` ${attribute}="${ssrAppId}"`; // build a string containing all attributes of this tag + var attrs = tag.once ? '' : " ".concat(attribute, "=\"").concat(ssrAppId, "\""); // build a string containing all attributes of this tag - for (const attr in tag) { + for (var attr in tag) { // these attributes are treated as children on the tag if (tagAttributeAsInnerContent.includes(attr) || attr === 'once') { continue; } // these form the attribute list for this tag - let prefix = ''; + var prefix = ''; if (dataAttributes.includes(attr)) { prefix = 'data-'; } if (attr === 'callback') { - attrs += ` onload="this.__vm_l=1"`; + attrs += " onload=\"this.__vm_l=1\""; continue; } - const isBooleanAttr = !prefix && booleanHtmlAttributes.includes(attr); + var isBooleanAttr = !prefix && booleanHtmlAttributes.includes(attr); if (isBooleanAttr && !tag[attr]) { continue; } - attrs += ` ${prefix}${attr}` + (isBooleanAttr ? '' : `="${tag[attr]}"`); + attrs += " ".concat(prefix).concat(attr) + (isBooleanAttr ? '' : "=\"".concat(tag[attr], "\"")); } - let json = ''; + var json = ''; if (tag.json) { json = JSON.stringify(tag.json); } // grab child content from one of these attributes, if possible - const content = tag.innerHTML || tag.cssText || json; // generate tag exactly without any other redundant attribute + var content = tag.innerHTML || tag.cssText || json; // generate tag exactly without any other redundant attribute // these tags have no end tag - const hasEndTag = !tagsWithoutEndTag.includes(type); // these tag types will have content inserted + var hasEndTag = !tagsWithoutEndTag.includes(type); // these tag types will have content inserted - const hasContent = hasEndTag && tagsWithInnerContent.includes(type); // the final string for this specific tag + var hasContent = hasEndTag && tagsWithInnerContent.includes(type); // the final string for this specific tag - return `${tagsStr}<${type}${attrs}${!hasContent && hasEndTag ? '/' : ''}>` + (hasContent ? `${content}</${type}>` : ''); + return "".concat(tagsStr, "<").concat(type).concat(attrs).concat(!hasContent && hasEndTag ? '/' : '', ">") + (hasContent ? "".concat(content, "</").concat(type, ">") : ''); }, ''); } - }; } @@ -1361,7 +1624,9 @@ function generateServerInjector(options, type, data) { return tagGenerator(options, type, data); } -function _inject(options = {}) { +function _inject() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** * Converts the state of the meta info object such that each item * can be compiled to a tag string on the server @@ -1371,9 +1636,9 @@ function _inject(options = {}) { */ return function inject() { // get meta info with sensible defaults - const metaInfo = getMetaInfo(options, this.$root, serverSequences); // generate server injectors + var metaInfo = getMetaInfo(options, this.$root, serverSequences); // generate server injectors - for (const key in metaInfo) { + for (var key in metaInfo) { if (!metaInfoOptionKeys.includes(key) && metaInfo.hasOwnProperty(key)) { metaInfo[key] = generateServerInjector(options, key, metaInfo[key]); } @@ -1383,10 +1648,12 @@ function _inject(options = {}) { }; } -function _$meta(options = {}) { - const _refresh$1 = _refresh(options); +function _$meta() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - const _inject$1 = _inject(options); + var _refresh$1 = _refresh(options); + + var _inject$1 = _inject(options); /** * Returns an injector for server-side rendering. * @this {Object} - the Vue instance (a root component) @@ -1396,7 +1663,9 @@ function _$meta(options = {}) { return function $meta() { return { - getOptions: () => getOptions(options), + getOptions: function getOptions$1() { + return getOptions(options); + }, refresh: _refresh$1.bind(this), inject: _inject$1.bind(this), pause: pause.bind(this), @@ -1410,7 +1679,9 @@ function _$meta(options = {}) { * @param {Function} Vue - the Vue constructor. */ -function install(Vue, options = {}) { +function install(Vue) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (Vue.__vuemeta_installed) { return; } @@ -1422,9 +1693,9 @@ function install(Vue, options = {}) { } var index = { - version, - install, - hasMetaInfo + version: version, + install: install, + hasMetaInfo: hasMetaInfo }; export default index; diff --git a/dist/vue-meta.js b/dist/vue-meta.js index 3341bb1..98b5e1f 100644 --- a/dist/vue-meta.js +++ b/dist/vue-meta.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.1.0 + * vue-meta v2.1.1 * (c) 2019 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -13,10 +13,10 @@ (global = global || self, global.VueMeta = factory()); }(this, function () { 'use strict'; - var version = "2.1.0"; + var version = "2.1.1"; // store an id to keep track of DOM updates - let batchId = null; + var batchId = null; function triggerUpdate(vm, hookName) { // if an update was triggered during initialization or when an update was triggered by the // metaInfo watcher, set initialized to null @@ -27,7 +27,9 @@ if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) { // batch potential DOM updates to prevent extraneous re-rendering - batchUpdate(() => vm.$meta().refresh()); + batchUpdate(function () { + return vm.$meta().refresh(); + }); } } /** @@ -38,14 +40,136 @@ * @return {Number} id - a new ID */ - function batchUpdate(callback, timeout = 10) { + function batchUpdate(callback) { + var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; clearTimeout(batchId); - batchId = setTimeout(() => { + batchId = setTimeout(function () { callback(); }, timeout); return batchId; } + function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + keys.push.apply(keys, symbols); + } + + return keys; + } + + function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(source, true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(source).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + /** * checks if passed argument is an array * @param {any} arg - the object to check @@ -58,10 +182,10 @@ return typeof arg === 'undefined'; } function isObject(arg) { - return typeof arg === 'object'; + return _typeof(arg) === 'object'; } function isPureObject(arg) { - return typeof arg === 'object' && arg !== null; + return _typeof(arg) === 'object' && arg !== null; } function isFunction(arg) { return typeof arg === 'function'; @@ -86,11 +210,13 @@ object[key].push(el); } - function hasMetaInfo(vm = this) { + function hasMetaInfo() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; return vm && (vm._vueMeta === true || isObject(vm._vueMeta)); } // a component is in a metaInfo branch when itself has meta info or one of its (grand-)children has - function inMetaInfoBranch(vm = this) { + function inMetaInfoBranch() { + var vm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; return vm && !isUndefined(vm._vueMeta); } @@ -102,16 +228,15 @@ } vm.$root._vueMeta.navGuards = true; - const $router = vm.$root.$router; - const $meta = vm.$root.$meta(); - $router.beforeEach((to, from, next) => { + var $router = vm.$root.$router; + var $meta = vm.$root.$meta(); + $router.beforeEach(function (to, from, next) { $meta.pause(); next(); }); - $router.afterEach(() => { - const { - metaInfo - } = $meta.resume(); + $router.afterEach(function () { + var _$meta$resume = $meta.resume(), + metaInfo = _$meta$resume.metaInfo; if (metaInfo && metaInfo.afterNavigation && isFunction(metaInfo.afterNavigation)) { metaInfo.afterNavigation(metaInfo); @@ -126,32 +251,35 @@ return false; } } - const hasGlobalWindow = hasGlobalWindowFn(); + var hasGlobalWindow = hasGlobalWindowFn(); - const _global = hasGlobalWindow ? window : global; + var _global = hasGlobalWindow ? window : global; - const console = _global.console = _global.console || {}; - function warn(...args) { + var console = _global.console = _global.console || {}; + function warn() { /* istanbul ignore next */ if (!console || !console.warn) { return; } - console.warn(...args); + console.warn.apply(console, arguments); } - const showWarningNotSupported = () => warn('This vue app/component has no vue-meta configuration'); + var showWarningNotSupported = function showWarningNotSupported() { + return warn('This vue app/component has no vue-meta configuration'); + }; - let appId = 1; + var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates return { - beforeCreate() { + beforeCreate: function beforeCreate() { + var _this = this; + Object.defineProperty(this, '_hasMetaInfo', { configurable: true, - - get() { + get: function get() { // Show deprecation warning once when devtools enabled if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) { warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead'); @@ -160,7 +288,6 @@ return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo // _vnode is used to know that it's attached to a real component // useful if we use some mixin to add some meta tags (like nuxt-i18n) @@ -168,7 +295,7 @@ if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) { if (!this.$root._vueMeta) { this.$root._vueMeta = { - appId + appId: appId }; appId++; } // to speed up updates we keep track of branches which have a component with vue-meta info defined @@ -177,7 +304,7 @@ if (!this._vueMeta) { this._vueMeta = true; - let p = this.$parent; + var p = this.$parent; while (p && p !== this.$root) { if (isUndefined(p._vueMeta)) { @@ -201,8 +328,8 @@ // 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) - ensuredPush(this.$options, 'created', () => { - this.$watch('$metaInfo', function () { + ensuredPush(this.$options, 'created', function () { + _this.$watch('$metaInfo', function () { triggerUpdate(this, 'watcher'); }); }); @@ -217,33 +344,37 @@ this.$root._vueMeta.initialized = this.$isServer; if (!this.$root._vueMeta.initialized) { - ensuredPush(this.$options, 'beforeMount', () => { + ensuredPush(this.$options, 'beforeMount', function () { // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if (this.$root.$el && this.$root.$el.hasAttribute && this.$root.$el.hasAttribute('data-server-rendered')) { - this.$root._vueMeta.appId = options.ssrAppId; + if (_this.$root.$el && _this.$root.$el.hasAttribute && _this.$root.$el.hasAttribute('data-server-rendered')) { + _this.$root._vueMeta.appId = options.ssrAppId; } }); // we use the mounted hook here as on page load - ensuredPush(this.$options, 'mounted', () => { - if (!this.$root._vueMeta.initialized) { + ensuredPush(this.$options, 'mounted', function () { + if (!_this.$root._vueMeta.initialized) { // used in triggerUpdate to check if a change was triggered // during initialization - this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded + _this.$root._vueMeta.initializing = true; // refresh meta in nextTick so all child components have loaded - this.$nextTick(function () { - const { - tags, - metaInfo - } = this.$root.$meta().refresh(); // After ssr hydration (identifier by tags === false) check + _this.$nextTick(function () { + var _this2 = this; + + var _this$$root$$meta$ref = this.$root.$meta().refresh(), + tags = _this$$root$$meta$ref.tags, + metaInfo = _this$$root$$meta$ref.metaInfo; // After ssr hydration (identifier by tags === false) check // if initialized was set to null in triggerUpdate. That'd mean // that during initilazation changes where triggered which need // to be applied OR a metaInfo watcher was triggered before the // current hook was called // (during initialization all changes are blocked) + if (tags === false && this.$root._vueMeta.initialized === null) { - this.$nextTick(() => triggerUpdate(this, 'initializing')); + this.$nextTick(function () { + return triggerUpdate(_this2, 'initializing'); + }); } this.$root._vueMeta.initialized = true; @@ -266,32 +397,33 @@ if (!this.$isServer) { // no need to add this hooks on server side - updateOnLifecycleHook.forEach(lifecycleHook => { - ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook)); + updateOnLifecycleHook.forEach(function (lifecycleHook) { + ensuredPush(_this.$options, lifecycleHook, function () { + return triggerUpdate(_this, lifecycleHook); + }); }); // re-render meta data when returning from a child component to parent - ensuredPush(this.$options, 'destroyed', () => { + ensuredPush(this.$options, 'destroyed', function () { // Wait that element is hidden before refreshing meta tags (to support animations) - const interval = setInterval(() => { - if (this.$el && this.$el.offsetParent !== null) { + var interval = setInterval(function () { + if (_this.$el && _this.$el.offsetParent !== null) { /* istanbul ignore next line */ return; } clearInterval(interval); - if (!this.$parent) { + if (!_this.$parent) { /* istanbul ignore next line */ return; } - triggerUpdate(this, 'destroyed'); + triggerUpdate(_this, 'destroyed'); }, 50); }); } } } - }; } @@ -299,7 +431,7 @@ * These are constant variables used throughout the application. */ // set some sane defaults - const defaultInfo = { + var defaultInfo = { title: undefined, titleChunk: '', titleTemplate: '%s', @@ -317,51 +449,51 @@ // gets converted to the various meta tags & attributes for the page. }; - const keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should + var keyName = 'metaInfo'; // This is the attribute vue-meta arguments on elements to know which it should // manage and which it should ignore. - const attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` + var attribute = 'data-vue-meta'; // This is the attribute that goes on the `html` tag to inform `vue-meta` // that the server has already generated the meta tags for the initial render. - const ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) + var ssrAttribute = 'data-vue-meta-server-rendered'; // This is the property that tells vue-meta to overwrite (instead of append) // an item in a tag list. For example, if you have two `meta` tag list items // that both have `vmid` of "description", then vue-meta will overwrite the // shallowest one with the deepest one. - const tagIDKeyName = 'vmid'; // This is the key name for possible meta templates + var tagIDKeyName = 'vmid'; // This is the key name for possible meta templates - const metaTemplateKeyName = 'template'; // This is the key name for the content-holding property + var metaTemplateKeyName = 'template'; // This is the key name for the content-holding property - const contentKeyName = 'content'; // The id used for the ssr app + var contentKeyName = 'content'; // The id used for the ssr app - const ssrAppId = 'ssr'; - const defaultOptions = { - keyName, - attribute, - ssrAttribute, - tagIDKeyName, - contentKeyName, - metaTemplateKeyName, - ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) + var ssrAppId = 'ssr'; + var defaultOptions = { + keyName: keyName, + attribute: attribute, + ssrAttribute: ssrAttribute, + tagIDKeyName: tagIDKeyName, + contentKeyName: contentKeyName, + metaTemplateKeyName: metaTemplateKeyName, + ssrAppId: ssrAppId // List of metaInfo property keys which are configuration options (and dont generate html) }; - const metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping + var metaInfoOptionKeys = ['titleChunk', 'titleTemplate', 'changed', '__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // The metaInfo property keys which are used to disable escaping - const disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags + var disableOptionKeys = ['__dangerouslyDisableSanitizers', '__dangerouslyDisableSanitizersByTagID']; // List of metaInfo property keys which only generates attributes and no tags - const metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event + var metaInfoAttributeKeys = ['htmlAttrs', 'headAttrs', 'bodyAttrs']; // HTML elements which support the onload event - const tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) + var tagsSupportingOnload = ['link', 'style', 'script']; // HTML elements which dont have a head tag (shortened to our needs) - const commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 + var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 - const booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; + var booleanHtmlAttributes = ['allowfullscreen', 'amp', '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']; function setOptions(options) { // combine options options = isObject(options) ? options : {}; - for (const key in defaultOptions) { + for (var key in defaultOptions) { if (!options[key]) { options[key] = defaultOptions[key]; } @@ -370,20 +502,24 @@ return options; } function getOptions(options) { - const optionsCopy = {}; + var optionsCopy = {}; - for (const key in options) { + for (var key in options) { optionsCopy[key] = options[key]; } return optionsCopy; } - function pause(refresh = true) { + function pause() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = true; - return () => resume(refresh); + return function () { + return resume(refresh); + }; } - function resume(refresh = true) { + function resume() { + var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.$root._vueMeta.paused = false; if (refresh) { @@ -391,11 +527,11 @@ } } - function applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName - }, headObject, template, chunk) { + function applyTemplate(_ref, headObject, template, chunk) { + var component = _ref.component, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; + if (isUndefined(template)) { template = headObject[metaTemplateKeyName]; delete headObject[metaTemplateKeyName]; @@ -423,61 +559,39 @@ * files in server/ still use normal js function */ function findIndex(array, predicate) { - if ( !Array.prototype.findIndex) { - // idx needs to be a Number, for..in returns string - for (let idx = 0; idx < array.length; idx++) { - if (predicate.call(arguments[2], array[idx], idx, array)) { - return idx; - } - } - - return -1; - } return array.findIndex(predicate, arguments[2]); } function toArray(arg) { - if ( !Array.from) { - return Array.prototype.slice.call(arg); - } return Array.from(arg); } function includes(array, value) { - if ( !Array.prototype.includes) { - for (const idx in array) { - if (array[idx] === value) { - return true; - } - } - - return false; - } return array.includes(value); } - const clientSequences = [[/&/g, '\u0026'], [/</g, '\u003C'], [/>/g, '\u003E'], [/"/g, '\u0022'], [/'/g, '\u0027']]; // sanitizes potentially dangerous characters + var clientSequences = [[/&/g, "&"], [/</g, "<"], [/>/g, ">"], [/"/g, "\""], [/'/g, "'"]]; // sanitizes potentially dangerous characters function escape(info, options, escapeOptions) { - const { - tagIDKeyName - } = options; - const { - doEscape = v => v, - escapeKeys - } = escapeOptions; - const escaped = {}; + var tagIDKeyName = options.tagIDKeyName; + var _escapeOptions$doEsca = escapeOptions.doEscape, + doEscape = _escapeOptions$doEsca === void 0 ? function (v) { + return v; + } : _escapeOptions$doEsca, + escapeKeys = escapeOptions.escapeKeys; + var escaped = {}; - for (const key in info) { - const value = info[key]; // no need to escape configuration options + for (var key in info) { + var value = info[key]; // no need to escape configuration options if (includes(metaInfoOptionKeys, key)) { escaped[key] = value; continue; } - let [disableKey] = disableOptionKeys; + var _disableOptionKeys = _slicedToArray(disableOptionKeys, 1), + disableKey = _disableOptionKeys[0]; if (escapeOptions[disableKey] && includes(escapeOptions[disableKey], key)) { // this info[key] doesnt need to escaped if the option is listed in __dangerouslyDisableSanitizers @@ -485,7 +599,7 @@ continue; } - const tagId = info[tagIDKeyName]; + var tagId = info[tagIDKeyName]; if (tagId) { disableKey = disableOptionKeys[1]; // keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped @@ -499,25 +613,25 @@ if (isString(value)) { escaped[key] = doEscape(value); } else if (isArray(value)) { - escaped[key] = value.map(v => { + escaped[key] = value.map(function (v) { if (isPureObject(v)) { - return escape(v, options, { ...escapeOptions, + return escape(v, options, _objectSpread2({}, escapeOptions, { escapeKeys: true - }); + })); } return doEscape(v); }); } else if (isPureObject(value)) { - escaped[key] = escape(value, options, { ...escapeOptions, + escaped[key] = escape(value, options, _objectSpread2({}, escapeOptions, { escapeKeys: true - }); + })); } else { escaped[key] = value; } if (escapeKeys) { - const escapedKey = doEscape(key); + var escapedKey = doEscape(key); if (key !== escapedKey) { escaped[escapedKey] = escaped[key]; @@ -534,7 +648,7 @@ }; function isNonNullObject(value) { - return !!value && typeof value === 'object'; + return !!value && _typeof(value) === 'object'; } function isSpecial(value) { @@ -632,25 +746,26 @@ var deepmerge_1 = deepmerge; var cjs = deepmerge_1; - function arrayMerge({ - component, - tagIDKeyName, - metaTemplateKeyName, - contentKeyName - }, target, source) { + function _arrayMerge(_ref, target, source) { + var component = _ref.component, + tagIDKeyName = _ref.tagIDKeyName, + metaTemplateKeyName = _ref.metaTemplateKeyName, + contentKeyName = _ref.contentKeyName; // we concat the arrays without merging objects contained in, // but we check for a `vmid` property on each object in the array // using an O(1) lookup associative array exploit - const destination = []; - target.forEach((targetItem, targetIndex) => { + var destination = []; + target.forEach(function (targetItem, targetIndex) { // no tagID so no need to check for duplicity if (!targetItem[tagIDKeyName]) { destination.push(targetItem); return; } - const sourceIndex = findIndex(source, item => item[tagIDKeyName] === targetItem[tagIDKeyName]); - const sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem + var sourceIndex = findIndex(source, function (item) { + return item[tagIDKeyName] === targetItem[tagIDKeyName]; + }); + var sourceItem = source[sourceIndex]; // source doesnt contain any duplicate vmid's, we can keep targetItem if (sourceIndex === -1) { destination.push(targetItem); @@ -676,33 +791,35 @@ } // now we only need to check if the target has a template to combine it with the source - const targetTemplate = targetItem[metaTemplateKeyName]; + var targetTemplate = targetItem[metaTemplateKeyName]; if (!targetTemplate) { return; } - const sourceTemplate = sourceItem[metaTemplateKeyName]; + var sourceTemplate = sourceItem[metaTemplateKeyName]; if (!sourceTemplate) { // use parent template and child content applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName }, sourceItem, targetTemplate); } else if (!sourceItem[contentKeyName]) { // use child template and parent content applyTemplate({ - component, - metaTemplateKeyName, - contentKeyName + component: component, + metaTemplateKeyName: metaTemplateKeyName, + contentKeyName: contentKeyName }, sourceItem, undefined, targetItem[contentKeyName]); } }); return destination.concat(source); } - function merge(target, source, options = {}) { + function merge(target, source) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // remove properties explicitly set to false so child components can // optionally _not_ overwrite the parents content // (for array properties this is checked in arrayMerge) @@ -710,12 +827,12 @@ delete source.title; } - metaInfoAttributeKeys.forEach(attrKey => { + metaInfoAttributeKeys.forEach(function (attrKey) { if (!source[attrKey]) { return; } - for (const key in source[attrKey]) { + for (var key in source[attrKey]) { if (source[attrKey].hasOwnProperty(key) && source[attrKey][key] === undefined) { if (includes(booleanHtmlAttributes, key)) { warn('VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details'); @@ -726,7 +843,9 @@ } }); return cjs(target, source, { - arrayMerge: (t, s) => arrayMerge(options, t, s) + arrayMerge: function arrayMerge(t, s) { + return _arrayMerge(options, t, s); + } }); } @@ -745,16 +864,15 @@ * @return {Object} result - final aggregated result */ - function getComponentOption(options = {}, component, result = {}) { - const { - keyName, - metaTemplateKeyName, - tagIDKeyName - } = options; - const { - $options, - $children - } = component; + function getComponentOption() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var keyName = options.keyName, + metaTemplateKeyName = options.metaTemplateKeyName, + tagIDKeyName = options.tagIDKeyName; + var $options = component.$options, + $children = component.$children; if (component._inactive) { return result; @@ -762,7 +880,7 @@ if ($options[keyName]) { - let data = $options[keyName]; // if option is a function, replace it with it's result + var data = $options[keyName]; // if option is a function, replace it with it's result if (isFunction(data)) { data = data.call(component); @@ -779,7 +897,7 @@ if ($children.length) { - $children.forEach(childComponent => { + $children.forEach(function (childComponent) { // check if the childComponent is in a branch // return otherwise so we dont walk all component branches unnecessarily if (!inMetaInfoBranch(childComponent)) { @@ -792,12 +910,16 @@ if (metaTemplateKeyName && result.meta) { // apply templates if needed - result.meta.forEach(metaObject => applyTemplate(options, metaObject)); // remove meta items with duplicate vmid's + result.meta.forEach(function (metaObject) { + return applyTemplate(options, metaObject); + }); // remove meta items with duplicate vmid's - result.meta = result.meta.filter((metaItem, index, arr) => { + result.meta = result.meta.filter(function (metaItem, index, arr) { return (// keep meta item if it doesnt has a vmid !metaItem.hasOwnProperty(tagIDKeyName) || // or if it's the first item in the array with this vmid - index === findIndex(arr, item => item[tagIDKeyName] === metaItem[tagIDKeyName]) + index === findIndex(arr, function (item) { + return item[tagIDKeyName] === metaItem[tagIDKeyName]; + }) ); }); } @@ -813,9 +935,12 @@ * @return {Object} - returned meta info */ - function getMetaInfo(options = {}, component, escapeSequences = []) { + function getMetaInfo() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var component = arguments.length > 1 ? arguments[1] : undefined; + var escapeSequences = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; // collect & aggregate all metaInfo $options - let info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta + var info = getComponentOption(options, component, defaultInfo); // Remove all "template" tags from meta // backup the title chunk in case user wants access to it if (info.title) { @@ -825,7 +950,7 @@ if (info.titleTemplate && info.titleTemplate !== '%s') { applyTemplate({ - component, + component: component, contentKeyName: 'title' }, info, info.titleTemplate, info.titleChunk || ''); } // convert base tag to an array so it can be handled the same way @@ -836,14 +961,22 @@ info.base = Object.keys(info.base).length ? [info.base] : []; } - const escapeOptions = { - doEscape: value => escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value) + var escapeOptions = { + doEscape: function doEscape(value) { + return escapeSequences.reduce(function (val, _ref) { + var _ref2 = _slicedToArray(_ref, 2), + v = _ref2[0], + r = _ref2[1]; + + return val.replace(v, r); + }, value); + } }; - disableOptionKeys.forEach((disableKey, index) => { + disableOptionKeys.forEach(function (disableKey, index) { if (index === 0) { ensureIsArray(info, disableKey); } else if (index === 1) { - for (const key in info[disableKey]) { + for (var key in info[disableKey]) { ensureIsArray(info[disableKey], key); } } @@ -862,23 +995,22 @@ return tags[tag]; } - function getElementsKey({ - body, - pbody - }) { + function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; return body ? 'body' : pbody ? 'pbody' : 'head'; } - function queryElements(parentNode, { - appId, - attribute, - type, - tagIDKeyName - }, attributes = {}) { - const queries = [`${type}[${attribute}="${appId}"]`, `${type}[data-${tagIDKeyName}]`].map(query => { - for (const key in attributes) { - const val = attributes[key]; - const attributeValue = val && val !== true ? `="${val}"` : ''; - query += `[data-${key}${attributeValue}]`; + function queryElements(parentNode, _ref2) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var queries = ["".concat(type, "[").concat(attribute, "=\"").concat(appId, "\"]"), "".concat(type, "[data-").concat(tagIDKeyName, "]")].map(function (query) { + for (var key in attributes) { + var val = attributes[key]; + var attributeValue = val && val !== true ? "=\"".concat(val, "\"") : ''; + query += "[data-".concat(key).concat(attributeValue, "]"); } return query; @@ -886,8 +1018,9 @@ return toArray(parentNode.querySelectorAll(queries.join(', '))); } - const callbacks = []; - function isDOMComplete(d = document) { + var callbacks = []; + function isDOMComplete() { + var d = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; return d.readyState === 'complete'; } function addCallback(query, callback) { @@ -898,18 +1031,37 @@ callbacks.push([query, callback]); } - function addCallbacks({ - tagIDKeyName - }, type, tags, autoAddListeners) { - let hasAsyncCallback = false; + function addCallbacks(_ref, type, tags, autoAddListeners) { + var tagIDKeyName = _ref.tagIDKeyName; + var hasAsyncCallback = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - for (const tag of tags) { - if (!tag[tagIDKeyName] || !tag.callback) { - continue; + try { + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var tag = _step.value; + + if (!tag[tagIDKeyName] || !tag.callback) { + continue; + } + + hasAsyncCallback = true; + addCallback("".concat(type, "[data-").concat(tagIDKeyName, "=\"").concat(tag[tagIDKeyName], "\"]"), tag.callback); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } - - hasAsyncCallback = true; - addCallback(`${type}[data-${tagIDKeyName}="${tag[tagIDKeyName]}"]`, tag.callback); } if (!autoAddListeners || !hasAsyncCallback) { @@ -927,14 +1079,18 @@ /* istanbul ignore next */ - document.onreadystatechange = () => { + document.onreadystatechange = function () { applyCallbacks(); }; } function applyCallbacks(matchElement) { - for (const [query, callback] of callbacks) { - const selector = `${query}[onload="this.__vm_l=1"]`; - let elements = []; + var _loop = function _loop() { + var _callbacks$_i = _slicedToArray(_callbacks[_i], 2), + query = _callbacks$_i[0], + callback = _callbacks$_i[1]; + + var selector = "".concat(query, "[onload=\"this.__vm_l=1\"]"); + var elements = []; if (!matchElement) { elements = toArray(document.querySelectorAll(selector)); @@ -944,47 +1100,78 @@ elements = [matchElement]; } - for (const element of elements) { - /* __vm_cb: whether the load callback has been called - * __vm_l: set by onload attribute, whether the element was loaded - * __vm_ev: whether the event listener was added or not - */ - if (element.__vm_cb) { - continue; - } + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; - const onload = () => { - /* Mark that the callback for this element has already been called, - * this prevents the callback to run twice in some (rare) conditions + try { + var _loop2 = function _loop2() { + var element = _step2.value; + + /* __vm_cb: whether the load callback has been called + * __vm_l: set by onload attribute, whether the element was loaded + * __vm_ev: whether the event listener was added or not */ - element.__vm_cb = true; - /* onload needs to be removed because we only need the - * attribute after ssr and if we dont remove it the node - * will fail isEqualNode on the client + if (element.__vm_cb) { + return "continue"; + } + + var onload = function onload() { + /* Mark that the callback for this element has already been called, + * this prevents the callback to run twice in some (rare) conditions + */ + element.__vm_cb = true; + /* onload needs to be removed because we only need the + * attribute after ssr and if we dont remove it the node + * will fail isEqualNode on the client + */ + + element.removeAttribute('onload'); + callback(element); + }; + /* IE9 doesnt seem to load scripts synchronously, + * causing a script sometimes/often already to be loaded + * when we add the event listener below (thus adding an onload event + * listener has no use because it will never be triggered). + * Therefore we add the onload attribute during ssr, and + * check here if it was already loaded or not */ - element.removeAttribute('onload'); - callback(element); + + if (element.__vm_l) { + onload(); + return "continue"; + } + + if (!element.__vm_ev) { + element.__vm_ev = true; + element.addEventListener('load', onload); + } }; - /* IE9 doesnt seem to load scripts synchronously, - * causing a script sometimes/often already to be loaded - * when we add the event listener below (thus adding an onload event - * listener has no use because it will never be triggered). - * Therefore we add the onload attribute during ssr, and - * check here if it was already loaded or not - */ + for (var _iterator2 = elements[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var _ret = _loop2(); - if (element.__vm_l) { - onload(); - continue; + if (_ret === "continue") continue; } - - if (!element.__vm_ev) { - element.__vm_ev = true; - element.addEventListener('load', onload); + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } } } + }; + + for (var _i = 0, _callbacks = callbacks; _i < _callbacks.length; _i++) { + _loop(); } } @@ -995,17 +1182,20 @@ * @param {HTMLElement} tag - the HTMLElement tag to update with new attrs */ - function updateAttribute({ - attribute - } = {}, attrs, tag) { - const vueMetaAttrString = tag.getAttribute(attribute); - const vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; - const toRemove = toArray(vueMetaAttrs); - const keepIndexes = []; + function updateAttribute() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + attribute = _ref.attribute; - for (const attr in attrs) { + var attrs = arguments.length > 1 ? arguments[1] : undefined; + var tag = arguments.length > 2 ? arguments[2] : undefined; + var vueMetaAttrString = tag.getAttribute(attribute); + var vueMetaAttrs = vueMetaAttrString ? vueMetaAttrString.split(',') : []; + var toRemove = toArray(vueMetaAttrs); + var keepIndexes = []; + + for (var attr in attrs) { if (attrs.hasOwnProperty(attr)) { - const value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; + var value = includes(booleanHtmlAttributes, attr) ? '' : isArray(attrs[attr]) ? attrs[attr].join(' ') : attrs[attr]; tag.setAttribute(attr, value || ''); if (!includes(vueMetaAttrs, attr)) { @@ -1017,7 +1207,9 @@ } } - const removedAttributesCount = toRemove.filter((el, index) => !includes(keepIndexes, index)).reduce((acc, attr) => { + var removedAttributesCount = toRemove.filter(function (el, index) { + return !includes(keepIndexes, index); + }).reduce(function (acc, attr) { tag.removeAttribute(attr); return acc + 1; }, 0); @@ -1051,20 +1243,23 @@ * @return {Object} - a representation of what tags changed */ - function updateTag(appId, options = {}, type, tags, head, body) { - const { - attribute, - tagIDKeyName - } = options; - const dataAttributes = [tagIDKeyName, ...commonDataAttributes]; - const newElements = []; - const queryOptions = { - appId, - attribute, - type, - tagIDKeyName + function updateTag(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var type = arguments.length > 2 ? arguments[2] : undefined; + var tags = arguments.length > 3 ? arguments[3] : undefined; + var head = arguments.length > 4 ? arguments[4] : undefined; + var body = arguments.length > 5 ? arguments[5] : undefined; + var attribute = options.attribute, + tagIDKeyName = options.tagIDKeyName; + var dataAttributes = [tagIDKeyName].concat(_toConsumableArray(commonDataAttributes)); + var newElements = []; + var queryOptions = { + appId: appId, + attribute: attribute, + type: type, + tagIDKeyName: tagIDKeyName }; - const currentElements = { + var currentElements = { head: queryElements(head, queryOptions), pbody: queryElements(body, queryOptions, { pbody: true @@ -1078,109 +1273,148 @@ // remove duplicates that could have been found by merging tags // which include a mixin with metaInfo and that mixin is used // by multiple components on the same page - const found = []; - tags = tags.filter(x => { - const k = JSON.stringify(x); - const res = !includes(found, k); + var found = []; + tags = tags.filter(function (x) { + var k = JSON.stringify(x); + var res = !includes(found, k); found.push(k); return res; }); } if (tags.length) { - for (const tag of tags) { - if (tag.skip) { - continue; - } + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - const newElement = document.createElement(type); - newElement.setAttribute(attribute, appId); + try { + var _loop = function _loop() { + var tag = _step.value; - for (const attr in tag) { - /* istanbul ignore next */ - if (!tag.hasOwnProperty(attr)) { - continue; + if (tag.skip) { + return "continue"; } - if (attr === 'innerHTML') { - newElement.innerHTML = tag.innerHTML; - continue; - } + var newElement = document.createElement(type); + newElement.setAttribute(attribute, appId); - if (attr === 'json') { - newElement.innerHTML = JSON.stringify(tag.json); - continue; - } - - if (attr === 'cssText') { - if (newElement.styleSheet) { - /* istanbul ignore next */ - newElement.styleSheet.cssText = tag.cssText; - } else { - newElement.appendChild(document.createTextNode(tag.cssText)); + var _loop2 = function _loop2(attr) { + /* istanbul ignore next */ + if (!tag.hasOwnProperty(attr)) { + return "continue"; } - continue; + if (attr === 'innerHTML') { + newElement.innerHTML = tag.innerHTML; + return "continue"; + } + + if (attr === 'json') { + newElement.innerHTML = JSON.stringify(tag.json); + return "continue"; + } + + if (attr === 'cssText') { + if (newElement.styleSheet) { + /* istanbul ignore next */ + newElement.styleSheet.cssText = tag.cssText; + } else { + newElement.appendChild(document.createTextNode(tag.cssText)); + } + + return "continue"; + } + + if (attr === 'callback') { + newElement.onload = function () { + return tag[attr](newElement); + }; + + return "continue"; + } + + var _attr = includes(dataAttributes, attr) ? "data-".concat(attr) : attr; + + var isBooleanAttribute = includes(booleanHtmlAttributes, attr); + + if (isBooleanAttribute && !tag[attr]) { + return "continue"; + } + + var value = isBooleanAttribute ? '' : tag[attr]; + newElement.setAttribute(_attr, value); + }; + + for (var attr in tag) { + var _ret2 = _loop2(attr); + + if (_ret2 === "continue") continue; } - if (attr === 'callback') { - newElement.onload = () => tag[attr](newElement); + var oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - continue; + var indexToDelete = void 0; + var hasEqualElement = oldElements.some(function (existingTag, index) { + indexToDelete = index; + return newElement.isEqualNode(existingTag); + }); + + if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { + oldElements.splice(indexToDelete, 1); + } else { + newElements.push(newElement); } + }; - const _attr = includes(dataAttributes, attr) ? `data-${attr}` : attr; + for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _ret = _loop(); - const isBooleanAttribute = includes(booleanHtmlAttributes, attr); - - if (isBooleanAttribute && !tag[attr]) { - continue; - } - - const value = isBooleanAttribute ? '' : tag[attr]; - newElement.setAttribute(_attr, value); + if (_ret === "continue") continue; } - - const oldElements = currentElements[getElementsKey(tag)]; // Remove a duplicate tag from domTagstoRemove, so it isn't cleared. - - let indexToDelete; - const hasEqualElement = oldElements.some((existingTag, index) => { - indexToDelete = index; - return newElement.isEqualNode(existingTag); - }); - - if (hasEqualElement && (indexToDelete || indexToDelete === 0)) { - oldElements.splice(indexToDelete, 1); - } else { - newElements.push(newElement); + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } } - let oldElements = []; + var oldElements = []; - for (const current of Object.values(currentElements)) { - oldElements = [...oldElements, ...current]; + for (var _i = 0, _Object$values = Object.values(currentElements); _i < _Object$values.length; _i++) { + var current = _Object$values[_i]; + oldElements = [].concat(_toConsumableArray(oldElements), _toConsumableArray(current)); } // remove old elements - for (const element of oldElements) { + for (var _i2 = 0, _oldElements = oldElements; _i2 < _oldElements.length; _i2++) { + var element = _oldElements[_i2]; element.parentNode.removeChild(element); } // insert new elements - for (const element of newElements) { - if (element.hasAttribute('data-body')) { - body.appendChild(element); + for (var _i3 = 0, _newElements = newElements; _i3 < _newElements.length; _i3++) { + var _element = _newElements[_i3]; + + if (_element.hasAttribute('data-body')) { + body.appendChild(_element); continue; } - if (element.hasAttribute('data-pbody')) { - body.insertBefore(element, body.firstChild); + if (_element.hasAttribute('data-pbody')) { + body.insertBefore(_element, body.firstChild); continue; } - head.appendChild(element); + head.appendChild(_element); } return { @@ -1195,24 +1429,44 @@ * @param {Object} newInfo - the meta info to update to */ - function updateClientMetaInfo(appId, options = {}, newInfo) { - const { - ssrAttribute, - ssrAppId - } = options; // only cache tags for current update + function updateClientMetaInfo(appId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var newInfo = arguments.length > 2 ? arguments[2] : undefined; + var ssrAttribute = options.ssrAttribute, + ssrAppId = options.ssrAppId; // only cache tags for current update - const tags = {}; - const htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update + var tags = {}; + var htmlTag = getTag(tags, 'html'); // if this is a server render, then dont update if (appId === ssrAppId && htmlTag.hasAttribute(ssrAttribute)) { // remove the server render attribute so we can update on (next) changes htmlTag.removeAttribute(ssrAttribute); // add load callbacks if the - let addLoadListeners = false; + var addLoadListeners = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - for (const type of tagsSupportingOnload) { - if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { - addLoadListeners = true; + try { + for (var _iterator = tagsSupportingOnload[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var type = _step.value; + + if (newInfo[type] && addCallbacks(options, type, newInfo[type])) { + addLoadListeners = true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } @@ -1224,50 +1478,52 @@ } // initialize tracked changes - const addedTags = {}; - const removedTags = {}; + var addedTags = {}; + var removedTags = {}; - for (const type in newInfo) { + for (var _type in newInfo) { // ignore these - if (includes(metaInfoOptionKeys, type)) { + if (includes(metaInfoOptionKeys, _type)) { continue; } - if (type === 'title') { + if (_type === 'title') { // update the title updateTitle(newInfo.title); continue; } - if (includes(metaInfoAttributeKeys, type)) { - const tagName = type.substr(0, 4); - updateAttribute(options, newInfo[type], getTag(tags, tagName)); + if (includes(metaInfoAttributeKeys, _type)) { + var tagName = _type.substr(0, 4); + + updateAttribute(options, newInfo[_type], getTag(tags, tagName)); continue; } // tags should always be an array, ignore if it isnt - if (!isArray(newInfo[type])) { + if (!isArray(newInfo[_type])) { continue; } - const { - oldTags, - newTags - } = updateTag(appId, options, type, newInfo[type], getTag(tags, 'head'), getTag(tags, 'body')); + var _updateTag = updateTag(appId, options, _type, newInfo[_type], getTag(tags, 'head'), getTag(tags, 'body')), + oldTags = _updateTag.oldTags, + newTags = _updateTag.newTags; if (newTags.length) { - addedTags[type] = newTags; - removedTags[type] = oldTags; + addedTags[_type] = newTags; + removedTags[_type] = oldTags; } } return { - addedTags, - removedTags + addedTags: addedTags, + removedTags: removedTags }; } - function _refresh(options = {}) { + function _refresh() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** * When called, will update the current meta info with new meta info. * Useful when updating meta info as the result of an asynchronous @@ -1279,9 +1535,9 @@ * @return {Object} - new meta info */ return function refresh() { - const metaInfo = getMetaInfo(options, this.$root, clientSequences); - const appId = this.$root._vueMeta.appId; - const tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info + var metaInfo = getMetaInfo(options, this.$root, clientSequences); + var appId = this.$root._vueMeta.appId; + var tags = updateClientMetaInfo(appId, options, metaInfo); // emit "event" with new info if (tags && isFunction(metaInfo.changed)) { metaInfo.changed(metaInfo, tags.addedTags, tags.removedTags); @@ -1289,16 +1545,18 @@ return { vm: this, - metaInfo, - tags + metaInfo: metaInfo, + tags: tags }; }; } - function _$meta(options = {}) { - const _refresh$1 = _refresh(options); + function _$meta() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - const inject = () => {}; + var _refresh$1 = _refresh(options); + + var inject = function inject() {}; /** * Returns an injector for server-side rendering. * @this {Object} - the Vue instance (a root component) @@ -1318,9 +1576,11 @@ } return { - getOptions: () => getOptions(options), + getOptions: function getOptions$1() { + return getOptions(options); + }, refresh: _refresh$1.bind(this), - inject, + inject: inject, pause: pause.bind(this), resume: resume.bind(this) }; @@ -1332,7 +1592,9 @@ * @param {Function} Vue - the Vue constructor. */ - function install(Vue, options = {}) { + function install(Vue) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (Vue.__vuemeta_installed) { return; } @@ -1350,9 +1612,9 @@ } var browser = { - version, - install, - hasMetaInfo + version: version, + install: install, + hasMetaInfo: hasMetaInfo }; return browser; diff --git a/dist/vue-meta.min.js b/dist/vue-meta.min.js index 6b51206..538d736 100644 --- a/dist/vue-meta.min.js +++ b/dist/vue-meta.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).VueMeta=t()}(this,function(){"use strict";let e=null;function t(t,n){t.$root._vueMeta.initialized||!t.$root._vueMeta.initializing&&"watcher"!==n||(t.$root._vueMeta.initialized=null),t.$root._vueMeta.initialized&&!t.$root._vueMeta.paused&&function(t,n=10){clearTimeout(e),e=setTimeout(()=>{t()},n)}(()=>t.$meta().refresh())}function n(e){return Array.isArray(e)}function o(e){return void 0===e}function r(e){return"object"==typeof e}function i(e){return"object"==typeof e&&null!==e}function a(e){return"function"==typeof e}function s(e,t){return t&&r(e)?(n(e[t])||(e[t]=[]),e):n(e)?e:[]}function u(e,t,n){s(e,t),e[t].push(n)}function c(e=this){return e&&(!0===e._vueMeta||r(e._vueMeta))}function l(e){if(e.$root._vueMeta.navGuards||!e.$root.$router)return;e.$root._vueMeta.navGuards=!0;const t=e.$root.$router,n=e.$root.$meta();t.beforeEach((e,t,o)=>{n.pause(),o()}),t.afterEach(()=>{const{metaInfo:e}=n.resume();e&&e.afterNavigation&&a(e.afterNavigation)&&e.afterNavigation(e)})}const f=function(){try{return!o(window)}catch(e){return!1}}()?window:global,d=f.console=f.console||{};function h(...e){d&&d.warn&&d.warn(...e)}const p=()=>h("This vue app/component has no vue-meta configuration");let m=1;const y={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},v={keyName:"metaInfo",attribute:"data-vue-meta",ssrAttribute:"data-vue-meta-server-rendered",tagIDKeyName:"vmid",contentKeyName:"content",metaTemplateKeyName:"template",ssrAppId:"ssr"},b=["titleChunk","titleTemplate","changed","__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],g=["__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],$=["htmlAttrs","headAttrs","bodyAttrs"],_=["link","style","script"],M=["body","pbody"],A=["allowfullscreen","amp","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"];function T(e=!0){return this.$root._vueMeta.paused=!0,()=>N(e)}function N(e=!0){if(this.$root._vueMeta.paused=!1,e)return this.$root.$meta().refresh()}function I({component:e,metaTemplateKeyName:t,contentKeyName:n},r,i,s){return o(i)&&(i=r[t],delete r[t]),!!i&&(o(s)&&(s=r[n]),r[n]=a(i)?i.call(e,s):i.replace(/%s/g,s),!0)}function w(e,t){if(!Array.prototype.findIndex){for(let n=0;n<e.length;n++)if(t.call(arguments[2],e[n],n,e))return n;return-1}return e.findIndex(t,arguments[2])}function O(e){return Array.from?Array.from(e):Array.prototype.slice.call(e)}function j(e,t){if(!Array.prototype.includes){for(const n in e)if(e[n]===t)return!0;return!1}return e.includes(t)}const S=[[/&/g,"&"],[/</g,"<"],[/>/g,">"],[/"/g,'"'],[/'/g,"'"]];var K=function(e){return function(e){return!!e&&"object"==typeof e}(e)&&!function(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||function(e){return e.$$typeof===k}(e)}(e)};var k="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function D(e,t){return!1!==t.clone&&t.isMergeableObject(e)?P((n=e,Array.isArray(n)?[]:{}),e,t):e;var n}function z(e,t,n){return e.concat(t).map(function(e){return D(e,n)})}function E(e){return Object.keys(e).concat(function(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return e.propertyIsEnumerable(t)}):[]}(e))}function x(e,t,n){var o={};return n.isMergeableObject(e)&&E(e).forEach(function(t){o[t]=D(e[t],n)}),E(t).forEach(function(r){n.isMergeableObject(t[r])&&e[r]?o[r]=function(e,t){if(!t.customMerge)return P;var n=t.customMerge(e);return"function"==typeof n?n:P}(r,n)(e[r],t[r],n):o[r]=D(t[r],n)}),o}function P(e,t,n){(n=n||{}).arrayMerge=n.arrayMerge||z,n.isMergeableObject=n.isMergeableObject||K;var o=Array.isArray(t);return o===Array.isArray(e)?o?n.arrayMerge(e,t,n):x(e,t,n):D(t,n)}P.all=function(e,t){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce(function(e,n){return P(e,n,t)},{})};var C=P;function L(e,t,n={}){return t.hasOwnProperty("title")&&void 0===t.title&&delete t.title,$.forEach(e=>{if(t[e])for(const n in t[e])t[e].hasOwnProperty(n)&&void 0===t[e][n]&&(j(A,n)&&h("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),delete t[e][n])}),C(e,t,{arrayMerge:(e,t)=>(function({component:e,tagIDKeyName:t,metaTemplateKeyName:n,contentKeyName:o},r,i){const a=[];return r.forEach((r,s)=>{if(!r[t])return void a.push(r);const u=w(i,e=>e[t]===r[t]),c=i[u];if(-1===u)return void a.push(r);if(c.hasOwnProperty(o)&&void 0===c[o]||c.hasOwnProperty("innerHTML")&&void 0===c.innerHTML)return a.push(r),void i.splice(u,1);if(null===c[o]||null===c.innerHTML)return void i.splice(u,1);const l=r[n];l&&(c[n]?c[o]||I({component:e,metaTemplateKeyName:n,contentKeyName:o},c,void 0,r[o]):I({component:e,metaTemplateKeyName:n,contentKeyName:o},c,l))}),a.concat(i)})(n,e,t)})}function H(e={},t,n={}){const{keyName:i,metaTemplateKeyName:s,tagIDKeyName:u}=e,{$options:c,$children:l}=t;if(t._inactive)return n;if(c[i]){let o=c[i];if(a(o)&&(o=o.call(t)),!r(o))return n;n=L(n,o,e)}return l.length&&l.forEach(t=>{(function(e=this){return e&&!o(e._vueMeta)})(t)&&(n=H(e,t,n))}),s&&n.meta&&(n.meta.forEach(t=>I(e,t)),n.meta=n.meta.filter((e,t,n)=>!e.hasOwnProperty(u)||t===w(n,t=>t[u]===e[u]))),n}function B(e={},t,o=[]){let r=H(e,t,y);r.title&&(r.titleChunk=r.title),r.titleTemplate&&"%s"!==r.titleTemplate&&I({component:t,contentKeyName:"title"},r,r.titleTemplate,r.titleChunk||""),r.base&&(r.base=Object.keys(r.base).length?[r.base]:[]);const a={doEscape:e=>o.reduce((e,[t,n])=>e.replace(t,n),e)};return g.forEach((e,t)=>{if(0===t)s(r,e);else if(1===t)for(const t in r[e])s(r[e],t);a[e]=r[e]}),r=function e(t,o,r){const{tagIDKeyName:a}=o,{doEscape:s=(e=>e),escapeKeys:u}=r,c={};for(const l in t){const f=t[l];if(j(b,l)){c[l]=f;continue}let[d]=g;if(r[d]&&j(r[d],l)){c[l]=f;continue}const h=t[a];if(h&&(d=g[1],r[d]&&r[d][h]&&j(r[d][h],l)))c[l]=f;else if("string"==typeof f?c[l]=s(f):n(f)?c[l]=f.map(t=>i(t)?e(t,o,{...r,escapeKeys:!0}):s(t)):i(f)?c[l]=e(f,o,{...r,escapeKeys:!0}):c[l]=f,u){const e=s(l);l!==e&&(c[e]=c[l],delete c[l])}}return c}(r,e,a)}function V(e,t){return e[t]||(e[t]=document.getElementsByTagName(t)[0]),e[t]}function q({body:e,pbody:t}){return e?"body":t?"pbody":"head"}function W(e,{appId:t,attribute:n,type:o,tagIDKeyName:r},i={}){const a=[`${o}[${n}="${t}"]`,`${o}[data-${r}]`].map(e=>{for(const t in i){const n=i[t];e+=`[data-${t}${n&&!0!==n?`="${n}"`:""}]`}return e});return O(e.querySelectorAll(a.join(", ")))}const G=[];function J(e,t){1===arguments.length&&(t=e,e=""),G.push([e,t])}function R({tagIDKeyName:e},t,n,o){let r=!1;for(const o of n)o[e]&&o.callback&&(r=!0,J(`${t}[data-${e}="${o[e]}"]`,o.callback));return o&&r?F():r}function F(){!function(e=document){return"complete"===e.readyState}()?document.onreadystatechange=()=>{Q()}:Q()}function Q(e){for(const[t,n]of G){const o=`${t}[onload="this.__vm_l=1"]`;let r=[];e||(r=O(document.querySelectorAll(o))),e&&e.matches(o)&&(r=[e]);for(const e of r){if(e.__vm_cb)continue;const t=()=>{e.__vm_cb=!0,e.removeAttribute("onload"),n(e)};e.__vm_l?t():e.__vm_ev||(e.__vm_ev=!0,e.addEventListener("load",t))}}}function U({attribute:e}={},t,o){const r=o.getAttribute(e),i=r?r.split(","):[],a=O(i),s=[];for(const e in t)if(t.hasOwnProperty(e)){const r=j(A,e)?"":n(t[e])?t[e].join(" "):t[e];o.setAttribute(e,r||""),j(i,e)||i.push(e),s.push(a.indexOf(e))}const u=a.filter((e,t)=>!j(s,t)).reduce((e,t)=>(o.removeAttribute(t),e+1),0);i.length===u?o.removeAttribute(e):o.setAttribute(e,i.sort().join(","))}function X(e,t={},n,o,r,i){const{attribute:a,tagIDKeyName:s}=t,u=[s,...M],c=[],l={appId:e,attribute:a,type:n,tagIDKeyName:s},f={head:W(r,l),pbody:W(i,l,{pbody:!0}),body:W(i,l,{body:!0})};if(o.length>1){const e=[];o=o.filter(t=>{const n=JSON.stringify(t),o=!j(e,n);return e.push(n),o})}if(o.length)for(const t of o){if(t.skip)continue;const o=document.createElement(n);o.setAttribute(a,e);for(const e in t){if(!t.hasOwnProperty(e))continue;if("innerHTML"===e){o.innerHTML=t.innerHTML;continue}if("json"===e){o.innerHTML=JSON.stringify(t.json);continue}if("cssText"===e){o.styleSheet?o.styleSheet.cssText=t.cssText:o.appendChild(document.createTextNode(t.cssText));continue}if("callback"===e){o.onload=()=>t[e](o);continue}const n=j(u,e)?`data-${e}`:e,r=j(A,e);if(r&&!t[e])continue;const i=r?"":t[e];o.setAttribute(n,i)}const r=f[q(t)];let i;r.some((e,t)=>(i=t,o.isEqualNode(e)))&&(i||0===i)?r.splice(i,1):c.push(o)}let d=[];for(const e of Object.values(f))d=[...d,...e];for(const e of d)e.parentNode.removeChild(e);for(const e of c)e.hasAttribute("data-body")?i.appendChild(e):e.hasAttribute("data-pbody")?i.insertBefore(e,i.firstChild):r.appendChild(e);return{oldTags:d,newTags:c}}function Y(e={}){return function(){const t=B(e,this.$root,S),o=function(e,t={},o){const{ssrAttribute:r,ssrAppId:i}=t,a={},s=V(a,"html");if(e===i&&s.hasAttribute(r)){s.removeAttribute(r);let e=!1;for(const n of _)o[n]&&R(t,n,o[n])&&(e=!0);return e&&F(),!1}const u={},c={};for(const r in o){if(j(b,r))continue;if("title"===r){((l=o.title)||""===l)&&(document.title=l);continue}if(j($,r)){const e=r.substr(0,4);U(t,o[r],V(a,e));continue}if(!n(o[r]))continue;const{oldTags:i,newTags:s}=X(e,t,r,o[r],V(a,"head"),V(a,"body"));s.length&&(u[r]=s,c[r]=i)}var l;return{addedTags:u,removedTags:c}}(this.$root._vueMeta.appId,e,t);return o&&a(t.changed)&&t.changed(t,o.addedTags,o.removedTags),{vm:this,metaInfo:t,tags:o}}}function Z(e,n={}){e.__vuemeta_installed||(e.__vuemeta_installed=!0,n=function(e){e=r(e)?e:{};for(const t in v)e[t]||(e[t]=v[t]);return e}(n),e.prototype.$meta=function(e={}){const t=Y(e),n=()=>{};return function(){return this.$root._vueMeta?{getOptions:()=>(function(e){const t={};for(const n in e)t[n]=e[n];return t})(e),refresh:t.bind(this),inject:n,pause:T.bind(this),resume:N.bind(this)}:{getOptions:p,refresh:p,inject:p,pause:p,resume:p}}}(n),e.mixin(function(e,n){const r=["activated","deactivated","beforeMount"];return{beforeCreate(){if(Object.defineProperty(this,"_hasMetaInfo",{configurable:!0,get(){return e.config.devtools&&!this.$root._vueMeta.hasMetaInfoDeprecationWarningShown&&(h("VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead"),this.$root._vueMeta.hasMetaInfoDeprecationWarningShown=!0),c(this)}}),!o(this.$options[n.keyName])&&null!==this.$options[n.keyName]){if(this.$root._vueMeta||(this.$root._vueMeta={appId:m},m++),!this._vueMeta){this._vueMeta=!0;let e=this.$parent;for(;e&&e!==this.$root;)o(e._vueMeta)&&(e._vueMeta=!1),e=e.$parent}a(this.$options[n.keyName])&&(this.$options.computed||(this.$options.computed={}),this.$options.computed.$metaInfo=this.$options[n.keyName],this.$isServer||u(this.$options,"created",()=>{this.$watch("$metaInfo",function(){t(this,"watcher")})})),o(this.$root._vueMeta.initialized)&&(this.$root._vueMeta.initialized=this.$isServer,this.$root._vueMeta.initialized||(u(this.$options,"beforeMount",()=>{this.$root.$el&&this.$root.$el.hasAttribute&&this.$root.$el.hasAttribute("data-server-rendered")&&(this.$root._vueMeta.appId=n.ssrAppId)}),u(this.$options,"mounted",()=>{this.$root._vueMeta.initialized||(this.$root._vueMeta.initializing=!0,this.$nextTick(function(){const{tags:e,metaInfo:o}=this.$root.$meta().refresh();!1===e&&null===this.$root._vueMeta.initialized&&this.$nextTick(()=>t(this,"initializing")),this.$root._vueMeta.initialized=!0,delete this.$root._vueMeta.initializing,!n.refreshOnceOnNavigation&&o.afterNavigation&&l(this)}))}),n.refreshOnceOnNavigation&&l(this))),this.$isServer||(r.forEach(e=>{u(this.$options,e,()=>t(this,e))}),u(this.$options,"destroyed",()=>{const e=setInterval(()=>{this.$el&&null!==this.$el.offsetParent||(clearInterval(e),this.$parent&&t(this,"destroyed"))},50)}))}}}}(e,n)))}return o(window)||o(window.Vue)||Z(window.Vue),{version:"2.1.0",install:Z,hasMetaInfo:c}}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).VueMeta=t()}(this,function(){"use strict";var e=null;function t(t,n){t.$root._vueMeta.initialized||!t.$root._vueMeta.initializing&&"watcher"!==n||(t.$root._vueMeta.initialized=null),t.$root._vueMeta.initialized&&!t.$root._vueMeta.paused&&function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10;clearTimeout(e),e=setTimeout(function(){t()},n)}(function(){return t.$meta().refresh()})}function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(n,!0).forEach(function(t){r(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(n).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function a(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,u=e[Symbol.iterator]();!(r=(a=u.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==u.return||u.return()}finally{if(o)throw i}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function u(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function c(e){return Array.isArray(e)}function l(e){return void 0===e}function s(e){return"object"===n(e)}function f(e){return"object"===n(e)&&null!==e}function d(e){return"function"==typeof e}function v(e,t){return t&&s(e)?(c(e[t])||(e[t]=[]),e):c(e)?e:[]}function h(e,t,n){v(e,t),e[t].push(n)}function p(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this;return e&&(!0===e._vueMeta||s(e._vueMeta))}function y(e){if(!e.$root._vueMeta.navGuards&&e.$root.$router){e.$root._vueMeta.navGuards=!0;var t=e.$root.$router,n=e.$root.$meta();t.beforeEach(function(e,t,r){n.pause(),r()}),t.afterEach(function(){var e=n.resume().metaInfo;e&&e.afterNavigation&&d(e.afterNavigation)&&e.afterNavigation(e)})}}var m=function(){try{return!l(window)}catch(e){return!1}}()?window:global,b=m.console=m.console||{};function g(){b&&b.warn&&b.warn.apply(b,arguments)}var $=function(){return g("This vue app/component has no vue-meta configuration")},_=1;var M={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},w={keyName:"metaInfo",attribute:"data-vue-meta",ssrAttribute:"data-vue-meta-server-rendered",tagIDKeyName:"vmid",contentKeyName:"content",metaTemplateKeyName:"template",ssrAppId:"ssr"},O=["titleChunk","titleTemplate","changed","__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],A=["__dangerouslyDisableSanitizers","__dangerouslyDisableSanitizersByTagID"],T=["htmlAttrs","headAttrs","bodyAttrs"],j=["link","style","script"],N=["body","pbody"],S=["allowfullscreen","amp","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"];function I(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return this.$root._vueMeta.paused=!0,function(){return D(e)}}function D(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];if(this.$root._vueMeta.paused=!1,e)return this.$root.$meta().refresh()}function k(e,t,n,r){var o=e.component,i=e.metaTemplateKeyName,a=e.contentKeyName;return l(n)&&(n=t[i],delete t[i]),!!n&&(l(r)&&(r=t[a]),t[a]=d(n)?n.call(o,r):n.replace(/%s/g,r),!0)}function E(e,t){return e.findIndex(t,arguments[2])}function K(e){return Array.from(e)}function P(e,t){return e.includes(t)}var z=[[/&/g,"&"],[/</g,"<"],[/>/g,">"],[/"/g,'"'],[/'/g,"'"]];var x=function(e){return function(e){return!!e&&"object"===n(e)}(e)&&!function(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||function(e){return e.$$typeof===C}(e)}(e)};var C="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function L(e,t){return!1!==t.clone&&t.isMergeableObject(e)?q((n=e,Array.isArray(n)?[]:{}),e,t):e;var n}function H(e,t,n){return e.concat(t).map(function(e){return L(e,n)})}function B(e){return Object.keys(e).concat(function(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return e.propertyIsEnumerable(t)}):[]}(e))}function V(e,t,n){var r={};return n.isMergeableObject(e)&&B(e).forEach(function(t){r[t]=L(e[t],n)}),B(t).forEach(function(o){n.isMergeableObject(t[o])&&e[o]?r[o]=function(e,t){if(!t.customMerge)return q;var n=t.customMerge(e);return"function"==typeof n?n:q}(o,n)(e[o],t[o],n):r[o]=L(t[o],n)}),r}function q(e,t,n){(n=n||{}).arrayMerge=n.arrayMerge||H,n.isMergeableObject=n.isMergeableObject||x;var r=Array.isArray(t);return r===Array.isArray(e)?r?n.arrayMerge(e,t,n):V(e,t,n):L(t,n)}q.all=function(e,t){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce(function(e,n){return q(e,n,t)},{})};var W=q;function G(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return t.hasOwnProperty("title")&&void 0===t.title&&delete t.title,T.forEach(function(e){if(t[e])for(var n in t[e])t[e].hasOwnProperty(n)&&void 0===t[e][n]&&(P(S,n)&&g("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),delete t[e][n])}),W(e,t,{arrayMerge:function(e,t){return function(e,t,n){var r=e.component,o=e.tagIDKeyName,i=e.metaTemplateKeyName,a=e.contentKeyName,u=[];return t.forEach(function(e,t){if(e[o]){var c=E(n,function(t){return t[o]===e[o]}),l=n[c];if(-1!==c){if(l.hasOwnProperty(a)&&void 0===l[a]||l.hasOwnProperty("innerHTML")&&void 0===l.innerHTML)return u.push(e),void n.splice(c,1);if(null!==l[a]&&null!==l.innerHTML){var s=e[i];s&&(l[i]?l[a]||k({component:r,metaTemplateKeyName:i,contentKeyName:a},l,void 0,e[a]):k({component:r,metaTemplateKeyName:i,contentKeyName:a},l,s))}else n.splice(c,1)}else u.push(e)}else u.push(e)}),u.concat(n)}(n,e,t)}})}function J(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=e.keyName,o=e.metaTemplateKeyName,i=e.tagIDKeyName,a=t.$options,u=t.$children;if(t._inactive)return n;if(a[r]){var c=a[r];if(d(c)&&(c=c.call(t)),!s(c))return n;n=G(n,c,e)}return u.length&&u.forEach(function(t){(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this;return e&&!l(e._vueMeta)})(t)&&(n=J(e,t,n))}),o&&n.meta&&(n.meta.forEach(function(t){return k(e,t)}),n.meta=n.meta.filter(function(e,t,n){return!e.hasOwnProperty(i)||t===E(n,function(t){return t[i]===e[i]})})),n}function R(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=J(e,t,M);r.title&&(r.titleChunk=r.title),r.titleTemplate&&"%s"!==r.titleTemplate&&k({component:t,contentKeyName:"title"},r,r.titleTemplate,r.titleChunk||""),r.base&&(r.base=Object.keys(r.base).length?[r.base]:[]);var o={doEscape:function(e){return n.reduce(function(e,t){var n=a(t,2),r=n[0],o=n[1];return e.replace(r,o)},e)}};return A.forEach(function(e,t){if(0===t)v(r,e);else if(1===t)for(var n in r[e])v(r[e],n);o[e]=r[e]}),r=function e(t,n,r){var o=n.tagIDKeyName,u=r.doEscape,l=void 0===u?function(e){return e}:u,s=r.escapeKeys,d={};for(var v in t){var h=t[v];if(P(O,v))d[v]=h;else{var p=a(A,1)[0];if(r[p]&&P(r[p],v))d[v]=h;else{var y=t[o];if(y&&(p=A[1],r[p]&&r[p][y]&&P(r[p][y],v)))d[v]=h;else if("string"==typeof h?d[v]=l(h):c(h)?d[v]=h.map(function(t){return f(t)?e(t,n,i({},r,{escapeKeys:!0})):l(t)}):f(h)?d[v]=e(h,n,i({},r,{escapeKeys:!0})):d[v]=h,s){var m=l(v);v!==m&&(d[m]=d[v],delete d[v])}}}}return d}(r,e,o)}function F(e,t){return e[t]||(e[t]=document.getElementsByTagName(t)[0]),e[t]}function Q(e,t){var n=t.appId,r=t.attribute,o=t.type,i=t.tagIDKeyName,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},u=["".concat(o,"[").concat(r,'="').concat(n,'"]'),"".concat(o,"[data-").concat(i,"]")].map(function(e){for(var t in a){var n=a[t],r=n&&!0!==n?'="'.concat(n,'"'):"";e+="[data-".concat(t).concat(r,"]")}return e});return K(e.querySelectorAll(u.join(", ")))}var U=[];function X(e,t){1===arguments.length&&(t=e,e=""),U.push([e,t])}function Y(e,t,n,r){var o=e.tagIDKeyName,i=!1,a=!0,u=!1,c=void 0;try{for(var l,s=n[Symbol.iterator]();!(a=(l=s.next()).done);a=!0){var f=l.value;f[o]&&f.callback&&(i=!0,X("".concat(t,"[data-").concat(o,'="').concat(f[o],'"]'),f.callback))}}catch(e){u=!0,c=e}finally{try{a||null==s.return||s.return()}finally{if(u)throw c}}return r&&i?Z():i}function Z(){!function(){return"complete"===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:document).readyState}()?document.onreadystatechange=function(){ee()}:ee()}function ee(e){for(var t=function(){var t=a(r[n],2),o=t[0],i=t[1],u="".concat(o,'[onload="this.__vm_l=1"]'),c=[];e||(c=K(document.querySelectorAll(u))),e&&e.matches(u)&&(c=[e]);var l=!0,s=!1,f=void 0;try{for(var d,v=function(){var e=d.value;if(e.__vm_cb)return"continue";var t=function(){e.__vm_cb=!0,e.removeAttribute("onload"),i(e)};if(e.__vm_l)return t(),"continue";e.__vm_ev||(e.__vm_ev=!0,e.addEventListener("load",t))},h=c[Symbol.iterator]();!(l=(d=h.next()).done);l=!0)v()}catch(e){s=!0,f=e}finally{try{l||null==h.return||h.return()}finally{if(s)throw f}}},n=0,r=U;n<r.length;n++)t()}function te(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).attribute,t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0,r=n.getAttribute(e),o=r?r.split(","):[],i=K(o),a=[];for(var u in t)if(t.hasOwnProperty(u)){var l=P(S,u)?"":c(t[u])?t[u].join(" "):t[u];n.setAttribute(u,l||""),P(o,u)||o.push(u),a.push(i.indexOf(u))}var s=i.filter(function(e,t){return!P(a,t)}).reduce(function(e,t){return n.removeAttribute(t),e+1},0);o.length===s?n.removeAttribute(e):n.setAttribute(e,o.sort().join(","))}function ne(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=arguments.length>3?arguments[3]:void 0,o=arguments.length>4?arguments[4]:void 0,i=arguments.length>5?arguments[5]:void 0,a=t.attribute,c=t.tagIDKeyName,l=[c].concat(u(N)),s=[],f={appId:e,attribute:a,type:n,tagIDKeyName:c},d={head:Q(o,f),pbody:Q(i,f,{pbody:!0}),body:Q(i,f,{body:!0})};if(r.length>1){var v=[];r=r.filter(function(e){var t=JSON.stringify(e),n=!P(v,t);return v.push(t),n})}if(r.length){var h=!0,p=!1,y=void 0;try{for(var m,b=function(){var t=m.value;if(t.skip)return"continue";var r=document.createElement(n);r.setAttribute(a,e);var o=function(e){if(!t.hasOwnProperty(e))return"continue";if("innerHTML"===e)return r.innerHTML=t.innerHTML,"continue";if("json"===e)return r.innerHTML=JSON.stringify(t.json),"continue";if("cssText"===e)return r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)),"continue";if("callback"===e)return r.onload=function(){return t[e](r)},"continue";var n=P(l,e)?"data-".concat(e):e,o=P(S,e);if(o&&!t[e])return"continue";var i=o?"":t[e];r.setAttribute(n,i)};for(var i in t)o(i);var u=d[function(e){var t=e.body,n=e.pbody;return t?"body":n?"pbody":"head"}(t)],c=void 0;u.some(function(e,t){return c=t,r.isEqualNode(e)})&&(c||0===c)?u.splice(c,1):s.push(r)},g=r[Symbol.iterator]();!(h=(m=g.next()).done);h=!0)b()}catch(e){p=!0,y=e}finally{try{h||null==g.return||g.return()}finally{if(p)throw y}}}for(var $=[],_=0,M=Object.values(d);_<M.length;_++){var w=M[_];$=[].concat(u($),u(w))}for(var O=0,A=$;O<A.length;O++){var T=A[O];T.parentNode.removeChild(T)}for(var j=0,I=s;j<I.length;j++){var D=I[j];D.hasAttribute("data-body")?i.appendChild(D):D.hasAttribute("data-pbody")?i.insertBefore(D,i.firstChild):o.appendChild(D)}return{oldTags:$,newTags:s}}function re(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return function(){var t=R(e,this.$root,z),n=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=t.ssrAttribute,o=t.ssrAppId,i={},a=F(i,"html");if(e===o&&a.hasAttribute(r)){a.removeAttribute(r);var u=!1,l=!0,s=!1,f=void 0;try{for(var d,v=j[Symbol.iterator]();!(l=(d=v.next()).done);l=!0){var h=d.value;n[h]&&Y(t,h,n[h])&&(u=!0)}}catch(e){s=!0,f=e}finally{try{l||null==v.return||v.return()}finally{if(s)throw f}}return u&&Z(),!1}var p,y={},m={};for(var b in n)if(!P(O,b))if("title"!==b){if(P(T,b)){var g=b.substr(0,4);te(t,n[b],F(i,g))}else if(c(n[b])){var $=ne(e,t,b,n[b],F(i,"head"),F(i,"body")),_=$.oldTags,M=$.newTags;M.length&&(y[b]=M,m[b]=_)}}else((p=n.title)||""===p)&&(document.title=p);return{addedTags:y,removedTags:m}}(this.$root._vueMeta.appId,e,t);return n&&d(t.changed)&&t.changed(t,n.addedTags,n.removedTags),{vm:this,metaInfo:t,tags:n}}}function oe(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e.__vuemeta_installed||(e.__vuemeta_installed=!0,n=function(e){for(var t in e=s(e)?e:{},w)e[t]||(e[t]=w[t]);return e}(n),e.prototype.$meta=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=re(e),n=function(){};return function(){return this.$root._vueMeta?{getOptions:function(){return function(e){var t={};for(var n in e)t[n]=e[n];return t}(e)},refresh:t.bind(this),inject:n,pause:I.bind(this),resume:D.bind(this)}:{getOptions:$,refresh:$,inject:$,pause:$,resume:$}}}(n),e.mixin(function(e,n){var r=["activated","deactivated","beforeMount"];return{beforeCreate:function(){var o=this;if(Object.defineProperty(this,"_hasMetaInfo",{configurable:!0,get:function(){return e.config.devtools&&!this.$root._vueMeta.hasMetaInfoDeprecationWarningShown&&(g("VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead"),this.$root._vueMeta.hasMetaInfoDeprecationWarningShown=!0),p(this)}}),!l(this.$options[n.keyName])&&null!==this.$options[n.keyName]){if(this.$root._vueMeta||(this.$root._vueMeta={appId:_},_++),!this._vueMeta){this._vueMeta=!0;for(var i=this.$parent;i&&i!==this.$root;)l(i._vueMeta)&&(i._vueMeta=!1),i=i.$parent}d(this.$options[n.keyName])&&(this.$options.computed||(this.$options.computed={}),this.$options.computed.$metaInfo=this.$options[n.keyName],this.$isServer||h(this.$options,"created",function(){o.$watch("$metaInfo",function(){t(this,"watcher")})})),l(this.$root._vueMeta.initialized)&&(this.$root._vueMeta.initialized=this.$isServer,this.$root._vueMeta.initialized||(h(this.$options,"beforeMount",function(){o.$root.$el&&o.$root.$el.hasAttribute&&o.$root.$el.hasAttribute("data-server-rendered")&&(o.$root._vueMeta.appId=n.ssrAppId)}),h(this.$options,"mounted",function(){o.$root._vueMeta.initialized||(o.$root._vueMeta.initializing=!0,o.$nextTick(function(){var e=this,r=this.$root.$meta().refresh(),o=r.tags,i=r.metaInfo;!1===o&&null===this.$root._vueMeta.initialized&&this.$nextTick(function(){return t(e,"initializing")}),this.$root._vueMeta.initialized=!0,delete this.$root._vueMeta.initializing,!n.refreshOnceOnNavigation&&i.afterNavigation&&y(this)}))}),n.refreshOnceOnNavigation&&y(this))),this.$isServer||(r.forEach(function(e){h(o.$options,e,function(){return t(o,e)})}),h(this.$options,"destroyed",function(){var e=setInterval(function(){o.$el&&null!==o.$el.offsetParent||(clearInterval(e),o.$parent&&t(o,"destroyed"))},50)}))}}}}(e,n)))}return l(window)||l(window.Vue)||oe(window.Vue),{version:"2.1.1",install:oe,hasMetaInfo:p}}); diff --git a/package.json b/package.json index 403c43d..d1710c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-meta", - "version": "2.1.0", + "version": "2.1.1", "description": "Manage HTML metadata in Vue.js components with ssr support", "keywords": [ "attribute",