diff --git a/CHANGELOG.md b/CHANGELOG.md index c160425..12f1ef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ 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.3.4](https://github.com/nuxt/vue-meta/compare/v2.3.3...v2.3.4) (2020-05-26) + + +### Features + +* add amp-boilerplate as boolean attribute (resolves: [#530](https://github.com/nuxt/vue-meta/issues/530)) ([#531](https://github.com/nuxt/vue-meta/issues/531)) ([bb45319](https://github.com/nuxt/vue-meta/commit/bb453195747058d90862d2db20d6a538ef04811f)) + + +### Bug Fixes + +* also set ssrAppId for first Vue app when ssrAttribute exists ([4cb5724](https://github.com/nuxt/vue-meta/commit/4cb57240da0fc486e63997d03d78b0639f9c2aa1)) +* also set ssrAppId for first Vue app when ssrAttribute exists ([#563](https://github.com/nuxt/vue-meta/issues/563)) ([4664df2](https://github.com/nuxt/vue-meta/commit/4664df2b1f4c972f883aa6f217a110243c8bc0c6)) +* auto install plugin in browser ([32fdb20](https://github.com/nuxt/vue-meta/commit/32fdb2001a5cb0b595c9db67d1b5a75da7f85902)) +* improve ssr detection when 1st metaInfo component isnt root ([a41b9a7](https://github.com/nuxt/vue-meta/commit/a41b9a73c0b90cf39d9c93fa66fe3e7d59494f77)) +* support falsy values in eg body attributes (fix: [#535](https://github.com/nuxt/vue-meta/issues/535)) ([1ef4108](https://github.com/nuxt/vue-meta/commit/1ef41080e72f6a3c745199ff2be1c20e69ba1157)) + ### [2.3.3](https://github.com/nuxt/vue-meta/compare/v2.3.2...v2.3.3) (2020-02-26) diff --git a/dist/vue-meta.common.js b/dist/vue-meta.common.js index 148b34a..b59ec24 100644 --- a/dist/vue-meta.common.js +++ b/dist/vue-meta.common.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.3.3 + * vue-meta v2.3.4 * (c) 2020 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -14,7 +14,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau var deepmerge = _interopDefault(require('deepmerge')); -var version = "2.3.3"; +var version = "2.3.4"; function _typeof(obj) { "@babel/helpers - typeof"; @@ -82,23 +82,91 @@ function _objectSpread2(target) { } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(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; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); +} + +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); +} + +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +function _createForOfIteratorHelper(o) { + if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { + var i = 0; + + var F = function () {}; + + return { + s: F, + n: function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }, + e: function (e) { + throw e; + }, + f: F + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var it, + normalCompletion = true, + didErr = false, + err; + return { + s: function () { + it = o[Symbol.iterator](); + }, + n: function () { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e: function (e) { + didErr = true; + err = e; + }, + f: function () { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; } /** @@ -226,7 +294,7 @@ var tagProperties = ['once', 'skip', 'template']; // Attributes which should be var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -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']; +var booleanHtmlAttributes = ['allowfullscreen', 'amp', 'amp-boilerplate', '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 batchId = null; function triggerUpdate(_ref, rootVm, hookName) { @@ -327,6 +395,48 @@ function includes(array, value) { return array.includes(value); } +var querySelector = function querySelector(arg, el) { + return (el || document).querySelectorAll(arg); +}; +function getTag(tags, tag) { + if (!tags[tag]) { + tags[tag] = document.getElementsByTagName(tag)[0]; + } + + return tags[tag]; +} +function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; + return body ? 'body' : pbody ? 'pbody' : 'head'; +} +function queryElements(parentNode, _ref2, attributes) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + attributes = attributes || {}; + 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 toArray(querySelector(queries.join(', '), parentNode)); +} +function removeElementsByAppId(_ref3, appId) { + var attribute = _ref3.attribute; + toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { + return el.remove(); + }); +} +function removeAttribute(el, attributeName) { + el.removeAttribute(attributeName); +} + function hasMetaInfo(vm) { vm = vm || this; return vm && (vm[rootConfigKey] === true || isObject(vm[rootConfigKey])); @@ -379,7 +489,8 @@ function addNavGuards(rootVm) { var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; + var wasServerRendered = false; // watch for client side component updates return { beforeCreate: function beforeCreate() { @@ -400,10 +511,26 @@ function createMixin(Vue, options) { return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo + }); + + if (this === $root) { + $root.$once('hook:beforeMount', function () { + wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered'); // In most cases when you have a SSR app it will be the first app thats gonna be + // initiated, if we cant detect the data-server-rendered attribute from Vue but we + // do see our own ssrAttribute then _assume_ the Vue app with appId 1 is the ssr app + // attempted fix for #404 & #562, but we rly need to refactor how we pass appIds from + // ssr to the client + + if (!wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1) { + var htmlTag = getTag({}, 'html'); + wasServerRendered = htmlTag && htmlTag.hasAttribute(options.ssrAttribute); + } + }); + } // 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($options[options.keyName]) || $options[options.keyName] === null) { return; } @@ -473,10 +600,10 @@ function createMixin(Vue, options) { if (!$root[rootConfigKey].initializedSsr) { $root[rootConfigKey].initializedSsr = true; this.$on('hook:beforeMount', function () { - var $root = this; // if this Vue-app was server rendered, set the appId to 'ssr' + var $root = this[rootKey]; // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) { + if (wasServerRendered) { $root[rootConfigKey].appId = options.ssrAppId; } }); @@ -486,37 +613,39 @@ function createMixin(Vue, options) { this.$on('hook:mounted', function () { var $root = this[rootKey]; - if (!$root[rootConfigKey].initialized) { - // used in triggerUpdate to check if a change was triggered - // during initialization - $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - - this.$nextTick(function () { - var _$root$$meta$refresh = $root.$meta().refresh(), - tags = _$root$$meta$refresh.tags, - metaInfo = _$root$$meta$refresh.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 ($root[rootConfigKey].initialized) { + return; + } // used in triggerUpdate to check if a change was triggered + // during initialization - if (tags === false && $root[rootConfigKey].initialized === null) { - this.$nextTick(function () { - return triggerUpdate(options, $root, 'init'); - }); - } + $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - $root[rootConfigKey].initialized = true; - delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet - // they are needed for the afterNavigation callback + this.$nextTick(function () { + var _$root$$meta$refresh = $root.$meta().refresh(), + tags = _$root$$meta$refresh.tags, + metaInfo = _$root$$meta$refresh.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 (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { - addNavGuards($root); - } - }); - } + + if (tags === false && $root[rootConfigKey].initialized === null) { + this.$nextTick(function () { + return triggerUpdate(options, $root, 'init'); + }); + } + + $root[rootConfigKey].initialized = true; + delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet + // they are needed for the afterNavigation callback + + if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { + addNavGuards($root); + } + }); }); // add the navigation guards if requested if (options.refreshOnceOnNavigation) { @@ -916,48 +1045,6 @@ function getComponentOption(options, component, result) { return result; } -var querySelector = function querySelector(arg, el) { - return (el || document).querySelectorAll(arg); -}; -function getTag(tags, tag) { - if (!tags[tag]) { - tags[tag] = document.getElementsByTagName(tag)[0]; - } - - return tags[tag]; -} -function getElementsKey(_ref) { - var body = _ref.body, - pbody = _ref.pbody; - return body ? 'body' : pbody ? 'pbody' : 'head'; -} -function queryElements(parentNode, _ref2, attributes) { - var appId = _ref2.appId, - attribute = _ref2.attribute, - type = _ref2.type, - tagIDKeyName = _ref2.tagIDKeyName; - attributes = attributes || {}; - 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 toArray(querySelector(queries.join(', '), parentNode)); -} -function removeElementsByAppId(_ref3, appId) { - var attribute = _ref3.attribute; - toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { - return el.remove(); - }); -} -function removeAttribute(el, attributeName) { - el.removeAttribute(attributeName); -} - var callbacks = []; function isDOMComplete(d) { return (d || document).readyState === 'complete'; @@ -1088,7 +1175,7 @@ function updateAttribute(appId, options, type, attrs, tag) { // which have been removed for this appId for (var attr in data) { - if (data[attr] && appId in data[attr]) { + if (data[attr] !== undefined && appId in data[attr]) { toUpdate.push(attr); if (!attrs[attr]) { @@ -1103,7 +1190,7 @@ function updateAttribute(appId, options, type, attrs, tag) { if (!attrData || attrData[appId] !== attrs[_attr]) { toUpdate.push(_attr); - if (attrs[_attr]) { + if (attrs[_attr] !== undefined) { data[_attr] = data[_attr] || {}; data[_attr][appId] = attrs[_attr]; } @@ -1120,7 +1207,9 @@ function updateAttribute(appId, options, type, attrs, tag) { } if (attrValues.length) { - var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(Boolean).join(' '); + var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(function (v) { + return v !== undefined; + }).join(' '); tag.setAttribute(_attr2, attrValue); } else { removeAttribute(tag, _attr2); @@ -1391,29 +1480,20 @@ function setMetaInfo(rootVm, appId, options, metaInfo) { function removeMetaInfo(rootVm, appId, options) { if (rootVm && rootVm.$el) { var tags = {}; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + + var _iterator = _createForOfIteratorHelper(metaInfoAttributeKeys), + _step; try { - for (var _iterator = metaInfoAttributeKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var type = _step.value; var tagName = type.substr(0, 4); updateAttribute(appId, options, type, {}, getTag(tags, tagName)); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } return removeElementsByAppId(options, appId); @@ -1760,7 +1840,7 @@ function generateServerInjector(options, metaInfo) { if (_data) { for (var _attr in _data) { - attributeData[_attr] = _objectSpread2({}, attributeData[_attr], _defineProperty({}, appId, _data[_attr])); + attributeData[_attr] = _objectSpread2(_objectSpread2({}, attributeData[_attr]), {}, _defineProperty({}, appId, _data[_attr])); } } } diff --git a/dist/vue-meta.esm.browser.js b/dist/vue-meta.esm.browser.js index 59e1acb..bf3ceac 100644 --- a/dist/vue-meta.esm.browser.js +++ b/dist/vue-meta.esm.browser.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.3.3 + * vue-meta v2.3.4 * (c) 2020 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -10,7 +10,7 @@ import deepmerge from 'deepmerge'; -var version = "2.3.3"; +var version = "2.3.4"; function _typeof(obj) { "@babel/helpers - typeof"; @@ -28,6 +28,78 @@ function _typeof(obj) { return _typeof(obj); } +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); +} + +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; +} + +function _createForOfIteratorHelper(o) { + if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { + var i = 0; + + var F = function () {}; + + return { + s: F, + n: function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }, + e: function (e) { + throw e; + }, + f: F + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var it, + normalCompletion = true, + didErr = false, + err; + return { + s: function () { + it = o[Symbol.iterator](); + }, + n: function () { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e: function (e) { + didErr = true; + err = e; + }, + f: function () { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; +} + /** * checks if passed argument is an array * @param {any} arg - the object to check @@ -149,7 +221,7 @@ var tagProperties = ['once', 'skip', 'template']; // Attributes which should be var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -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']; +var booleanHtmlAttributes = ['allowfullscreen', 'amp', 'amp-boilerplate', '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 batchId = null; function triggerUpdate(_ref, rootVm, hookName) { @@ -250,6 +322,48 @@ function includes(array, value) { return array.includes(value); } +var querySelector = function querySelector(arg, el) { + return (el || document).querySelectorAll(arg); +}; +function getTag(tags, tag) { + if (!tags[tag]) { + tags[tag] = document.getElementsByTagName(tag)[0]; + } + + return tags[tag]; +} +function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; + return body ? 'body' : pbody ? 'pbody' : 'head'; +} +function queryElements(parentNode, _ref2, attributes) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + attributes = attributes || {}; + 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 toArray(querySelector(queries.join(', '), parentNode)); +} +function removeElementsByAppId(_ref3, appId) { + var attribute = _ref3.attribute; + toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { + return el.remove(); + }); +} +function removeAttribute(el, attributeName) { + el.removeAttribute(attributeName); +} + function hasMetaInfo(vm) { vm = vm || this; return vm && (vm[rootConfigKey] === true || isObject(vm[rootConfigKey])); @@ -302,7 +416,8 @@ function addNavGuards(rootVm) { var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; + var wasServerRendered = false; // watch for client side component updates return { beforeCreate: function beforeCreate() { @@ -323,10 +438,26 @@ function createMixin(Vue, options) { return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo + }); + + if (this === $root) { + $root.$once('hook:beforeMount', function () { + wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered'); // In most cases when you have a SSR app it will be the first app thats gonna be + // initiated, if we cant detect the data-server-rendered attribute from Vue but we + // do see our own ssrAttribute then _assume_ the Vue app with appId 1 is the ssr app + // attempted fix for #404 & #562, but we rly need to refactor how we pass appIds from + // ssr to the client + + if (!wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1) { + var htmlTag = getTag({}, 'html'); + wasServerRendered = htmlTag && htmlTag.hasAttribute(options.ssrAttribute); + } + }); + } // 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($options[options.keyName]) || $options[options.keyName] === null) { return; } @@ -396,10 +527,10 @@ function createMixin(Vue, options) { if (!$root[rootConfigKey].initializedSsr) { $root[rootConfigKey].initializedSsr = true; this.$on('hook:beforeMount', function () { - var $root = this; // if this Vue-app was server rendered, set the appId to 'ssr' + var $root = this[rootKey]; // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) { + if (wasServerRendered) { $root[rootConfigKey].appId = options.ssrAppId; } }); @@ -409,37 +540,39 @@ function createMixin(Vue, options) { this.$on('hook:mounted', function () { var $root = this[rootKey]; - if (!$root[rootConfigKey].initialized) { - // used in triggerUpdate to check if a change was triggered - // during initialization - $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - - this.$nextTick(function () { - var _$root$$meta$refresh = $root.$meta().refresh(), - tags = _$root$$meta$refresh.tags, - metaInfo = _$root$$meta$refresh.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 ($root[rootConfigKey].initialized) { + return; + } // used in triggerUpdate to check if a change was triggered + // during initialization - if (tags === false && $root[rootConfigKey].initialized === null) { - this.$nextTick(function () { - return triggerUpdate(options, $root, 'init'); - }); - } + $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - $root[rootConfigKey].initialized = true; - delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet - // they are needed for the afterNavigation callback + this.$nextTick(function () { + var _$root$$meta$refresh = $root.$meta().refresh(), + tags = _$root$$meta$refresh.tags, + metaInfo = _$root$$meta$refresh.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 (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { - addNavGuards($root); - } - }); - } + + if (tags === false && $root[rootConfigKey].initialized === null) { + this.$nextTick(function () { + return triggerUpdate(options, $root, 'init'); + }); + } + + $root[rootConfigKey].initialized = true; + delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet + // they are needed for the afterNavigation callback + + if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { + addNavGuards($root); + } + }); }); // add the navigation guards if requested if (options.refreshOnceOnNavigation) { @@ -838,48 +971,6 @@ function getComponentOption(options, component, result) { return result; } -var querySelector = function querySelector(arg, el) { - return (el || document).querySelectorAll(arg); -}; -function getTag(tags, tag) { - if (!tags[tag]) { - tags[tag] = document.getElementsByTagName(tag)[0]; - } - - return tags[tag]; -} -function getElementsKey(_ref) { - var body = _ref.body, - pbody = _ref.pbody; - return body ? 'body' : pbody ? 'pbody' : 'head'; -} -function queryElements(parentNode, _ref2, attributes) { - var appId = _ref2.appId, - attribute = _ref2.attribute, - type = _ref2.type, - tagIDKeyName = _ref2.tagIDKeyName; - attributes = attributes || {}; - 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 toArray(querySelector(queries.join(', '), parentNode)); -} -function removeElementsByAppId(_ref3, appId) { - var attribute = _ref3.attribute; - toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { - return el.remove(); - }); -} -function removeAttribute(el, attributeName) { - el.removeAttribute(attributeName); -} - var callbacks = []; function isDOMComplete(d) { return (d || document).readyState === 'complete'; @@ -1010,7 +1101,7 @@ function updateAttribute(appId, options, type, attrs, tag) { // which have been removed for this appId for (var attr in data) { - if (data[attr] && appId in data[attr]) { + if (data[attr] !== undefined && appId in data[attr]) { toUpdate.push(attr); if (!attrs[attr]) { @@ -1025,7 +1116,7 @@ function updateAttribute(appId, options, type, attrs, tag) { if (!attrData || attrData[appId] !== attrs[_attr]) { toUpdate.push(_attr); - if (attrs[_attr]) { + if (attrs[_attr] !== undefined) { data[_attr] = data[_attr] || {}; data[_attr][appId] = attrs[_attr]; } @@ -1042,7 +1133,9 @@ function updateAttribute(appId, options, type, attrs, tag) { } if (attrValues.length) { - var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(Boolean).join(' '); + var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(function (v) { + return v !== undefined; + }).join(' '); tag.setAttribute(_attr2, attrValue); } else { removeAttribute(tag, _attr2); @@ -1313,29 +1406,20 @@ function setMetaInfo(rootVm, appId, options, metaInfo) { function removeMetaInfo(rootVm, appId, options) { if (rootVm && rootVm.$el) { var tags = {}; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + + var _iterator = _createForOfIteratorHelper(metaInfoAttributeKeys), + _step; try { - for (var _iterator = metaInfoAttributeKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var type = _step.value; var tagName = type.substr(0, 4); updateAttribute(appId, options, type, {}, getTag(tags, tagName)); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } return removeElementsByAppId(options, appId); @@ -1538,6 +1622,14 @@ function install(Vue, options) { Vue.mixin(createMixin(Vue, options)); } +{ + // automatic install + if (!isUndefined(window) && !isUndefined(window.Vue)) { + /* istanbul ignore next */ + install(window.Vue); + } +} + var index = { version: version, install: install, diff --git a/dist/vue-meta.esm.browser.min.js b/dist/vue-meta.esm.browser.min.js index f5690e3..4ea9729 100644 --- a/dist/vue-meta.esm.browser.min.js +++ b/dist/vue-meta.esm.browser.min.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.3.3 + * vue-meta v2.3.4 * (c) 2020 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -7,4 +7,4 @@ * - All the amazing contributors * @license MIT */ -import n from"deepmerge";function t(n){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n})(n)}function e(n){return Array.isArray(n)}function r(n){return void 0===n}function i(n){return"object"===t(n)}function o(n){return"object"===t(n)&&null!==n}function a(n){return"function"==typeof n}var u=(function(){try{return!r(window)}catch(n){return!1}}()?window:global).console||{};function f(n){u&&u.warn&&u.warn(n)}var c=function(n){return f("".concat(n," is not supported in browser builds"))},s={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},d="metaInfo",l="data-vue-meta",v="data-vue-meta-server-rendered",m="vmid",h="content",p="template",y=!0,b=10,g="ssr",I=Object.keys(s),A=[I[12],I[13]],N=[I[1],I[2],"changed"].concat(A),T=[I[3],I[4],I[5]],w=["link","style","script"],O=["once","skip","template"],k=["body","pbody"],M=["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"],S=null;function j(n,t,e){var r=n.t;t._vueMeta.i||!t._vueMeta.o&&"watcher"!==e||(t._vueMeta.i=null),t._vueMeta.i&&!t._vueMeta.u&&function(n,t){if(!(t=void 0===t?10:t))return void n();clearTimeout(S),S=setTimeout((function(){n()}),t)}((function(){t.$meta().refresh()}),r)}function K(n,t,e){if(!Array.prototype.findIndex){for(var r=0;r/g,">"],[/"/g,'"'],[/'/g,"'"]];function L(n,t,r){r=r||[];var i={A:function(n){return r.reduce((function(n,t){return n.replace(t[0],t[1])}),n)}};return A.forEach((function(n,e){if(0===e)C(t,n);else if(1===e)for(var r in t[n])C(t[n],r);i[n]=t[n]})),function n(t,r,i,a){var u=r.j,f=i.A,c=void 0===f?function(n){return n}:f,s={};for(var d in t){var l=t[d];if(D(N,d))s[d]=l;else{var v=A[0];if(i[v]&&D(i[v],d))s[d]=l;else{var m=t[u];if(m&&(v=A[1],i[v]&&i[v][m]&&D(i[v][m],d)))s[d]=l;else if("string"==typeof l?s[d]=c(l):e(l)?s[d]=l.map((function(t){return o(t)?n(t,r,i,!0):c(t)})):o(l)?s[d]=n(l,r,i,!0):s[d]=l,a){var h=c(d);d!==h&&(s[h]=s[d],delete s[d])}}}}return s}(t,n,i)}function P(n,t,e,i){var o=n.component,u=n.N,f=n.T;return!0!==e&&!0!==t[u]&&(r(e)&&t[u]&&(e=t[u],t[u]=!0),e?(r(i)&&(i=t[f]),t[f]=a(e)?e.call(o,i):e.replace(/%s/g,i),!0):(delete t[u],!1))}var R=!1;function $(t,e,r){return r=r||{},void 0===e.title&&delete e.title,T.forEach((function(n){if(e[n])for(var t in e[n])t in e[n]&&void 0===e[n][t]&&(D(M,t)&&!R&&(f("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),R=!0),delete e[n][t])})),n(t,e,{O:function(n,t){return function(n,t,e){var r=n.component,i=n.j,o=n.N,a=n.T,u=[];return t.length||e.length?(t.forEach((function(n,t){if(n[i]){var f=K(e,(function(t){return t[i]===n[i]})),c=e[f];if(-1!==f){if(a in c&&void 0===c[a]||"innerHTML"in c&&void 0===c.innerHTML)return u.push(n),void e.splice(f,1);if(null!==c[a]&&null!==c.innerHTML){var s=n[o];if(s){if(!c[o])return P({component:r,N:o,T:a},c,s),void(c.template=!0);c[a]||P({component:r,N:o,T:a},c,void 0,n[a])}}else e.splice(f,1)}else u.push(n)}else u.push(n)})),u.concat(e)):u}(r,n,t)}})}function q(n,t){return function n(t,e,o){if(o=o||{},e._inactive)return o;var a=(t=t||{}).v,u=e.$metaInfo,f=e.$options,c=e.$children;if(f[a]){var s=u||f[a];i(s)&&(o=$(o,s,t))}c.length&&c.forEach((function(e){(function(n){return(n=n||this)&&!r(n._vueMeta)})(e)&&(o=n(t,e,o))}));return o}(n||{},t,s)}var E=function(n,t){return(t||document).querySelectorAll(n)};function U(n,t){return n[t]||(n[t]=document.getElementsByTagName(t)[0]),n[t]}function F(n,t,e){var r=t.m,i=t.k,o=t.type,a=t.j;e=e||{};var u=["".concat(o,"[").concat(i,'="').concat(r,'"]'),"".concat(o,"[data-").concat(a,"]")].map((function(n){for(var t in e){var r=e[t],i=r&&!0!==r?'="'.concat(r,'"'):"";n+="[data-".concat(t).concat(i,"]")}return n}));return _(E(u.join(", "),n))}function G(n,t){n.removeAttribute(t)}var Q=[];function X(n,t,e,r){var i=n.j,o=!1;return e.forEach((function(n){n[i]&&n.callback&&(o=!0,function(n,t){1===arguments.length&&(t=n,n=""),Q.push([n,t])}("".concat(t,"[data-").concat(i,'="').concat(n[i],'"]'),n.callback))})),r&&o?Y():o}function Y(){var n;"complete"!==(n||document).readyState?document.onreadystatechange=function(){Z()}:Z()}function Z(n){Q.forEach((function(t){var e=t[0],r=t[1],i="".concat(e,'[onload="this.__vm_l=1"]'),o=[];n||(o=_(E(i))),n&&n.matches(i)&&(o=[n]),o.forEach((function(n){if(!n.__vm_cb){var t=function(){n.__vm_cb=!0,G(n,"onload"),r(n)};n.__vm_l?t():n.__vm_ev||(n.__vm_ev=!0,n.addEventListener("load",t))}}))}))}var nn,tn={};function en(n,t,e,r,i){var o=(t||{}).k,a=i.getAttribute(o);a&&(tn[e]=JSON.parse(decodeURI(a)),G(i,o));var u=tn[e]||{},f=[];for(var c in u)u[c]&&n in u[c]&&(f.push(c),r[c]||delete u[c][n]);for(var s in r){var d=u[s];d&&d[n]===r[s]||(f.push(s),r[s]&&(u[s]=u[s]||{},u[s][n]=r[s]))}for(var l=0,v=f;l1){var v=[];r=r.filter((function(n){var t=JSON.stringify(n),e=!D(v,t);return v.push(t),e}))}r.forEach((function(t){if(!t.skip){var r=document.createElement(e);t.once||r.setAttribute(u,n),Object.keys(t).forEach((function(n){if(!D(O,n))if("innerHTML"!==n)if("json"!==n)if("cssText"!==n)if("callback"!==n){var e=D(c,n)?"data-".concat(n):n,i=D(M,n);if(!i||t[n]){var o=i?"":t[n];r.setAttribute(e,o)}}else r.onload=function(){return t[n](r)};else r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText));else r.innerHTML=JSON.stringify(t.json);else r.innerHTML=t.innerHTML}));var i,o=l[function(n){var t=n.body,e=n.pbody;return t?"body":e?"pbody":"head"}(t)];o.some((function(n,t){return i=t,r.isEqualNode(n)}))&&(i||0===i)?o.splice(i,1):s.push(r)}}));var m=[];for(var h in l)Array.prototype.push.apply(m,l[h]);return m.forEach((function(n){n.parentNode.removeChild(n)})),s.forEach((function(n){n.hasAttribute("data-body")?o.appendChild(n):n.hasAttribute("data-pbody")?o.insertBefore(n,o.firstChild):i.appendChild(n)})),{oldTags:m,newTags:s}}function on(n,t,r){var i=t=t||{},o=i.M,a=i.h,u={},f=U(u,"html");if(n===a&&f.hasAttribute(o)){G(f,o);var c=!1;return w.forEach((function(n){r[n]&&X(t,n,r[n])&&(c=!0)})),c&&Y(),!1}var s,d={},l={};for(var v in r)if(!D(N,v))if("title"!==v){if(D(T,v)){var m=v.substr(0,4);en(n,t,v,r[v],U(u,m))}else if(e(r[v])){var h=rn(n,t,v,r[v],U(u,"head"),U(u,"body")),p=h.oldTags,y=h.newTags;y.length&&(d[v]=y,l[v]=p)}}else((s=r.title)||""===s)&&(document.title=s);return{S:d,D:l}}function an(n,t,e){return{set:function(r){return function(n,t,e,r){if(n&&n.$el)return on(t,e,r);(nn=nn||{})[t]=r}(n,t,e,r)},remove:function(){return function(n,t,e){if(n&&n.$el){var r={},i=!0,o=!1,a=void 0;try{for(var u,f=T[Symbol.iterator]();!(i=(u=f.next()).done);i=!0){var c=u.value,s=c.substr(0,4);en(t,e,c,{},U(r,s))}}catch(n){o=!0,a=n}finally{try{i||null==f.return||f.return()}finally{if(o)throw a}}return function(n,t){var e=n.k;_(E("[".concat(e,'="').concat(t,'"]'))).map((function(n){return n.remove()}))}(e,t)}nn[t]&&(delete nn[t],fn())}(n,t,e)}}}function un(){return nn}function fn(n){!n&&Object.keys(nn).length||(nn=void 0)}function cn(n,t){if(t=t||{},!n._vueMeta)return f("This vue app/component has no vue-meta configuration"),{};var e=function(n,t,e,r){e=e||[];var i=(n=n||{}).j;return t.title&&(t.titleChunk=t.title),t.titleTemplate&&"%s"!==t.titleTemplate&&P({component:r,T:"title"},t,t.titleTemplate,t.titleChunk||""),t.base&&(t.base=Object.keys(t.base).length?[t.base]:[]),t.meta&&(t.meta=t.meta.filter((function(n,t,e){return!n[i]||t===K(e,(function(t){return t[i]===n[i]}))})),t.meta.forEach((function(t){return P(n,t)}))),L(n,t,e)}(t,q(t,n),H,n),r=on(n._vueMeta.m,t,e);r&&a(e.changed)&&(e.changed(e,r.S,r.D),r={addedTags:r.S,removedTags:r.D});var i=un();if(i){for(var o in i)on(o,t,i[o]),delete i[o];fn(!0)}return{vm:n,metaInfo:e,tags:r}}function sn(n){n=n||{};var t=this.$root;return{getOptions:function(){return function(n){var t={};for(var e in n)t[e]=n[e];return t}(n)},setOptions:function(e){e&&e.p&&(n.p=!!e.p,B(t));if(e&&"debounceWait"in e){var r=parseInt(e.t);isNaN(r)||(n.t=r)}e&&"waitOnDestroyed"in e&&(n.g=!!e.g)},refresh:function(){return cn(t,n)},inject:function(){return c("inject")},pause:function(){return V(t)},resume:function(){return z(t)},addApp:function(e){return an(t,e,n)}}}var dn={version:"2.3.3",install:function(n,t){n.__vuemeta_installed||(n.__vuemeta_installed=!0,t=function(n){return{v:(n=i(n)?n:{}).keyName||d,k:n.attribute||l,M:n.ssrAttribute||v,j:n.tagIDKeyName||m,T:n.contentKeyName||h,N:n.metaTemplateKeyName||p,t:r(n.debounceWait)?b:n.debounceWait,g:r(n.waitOnDestroyed)?y:n.waitOnDestroyed,h:n.ssrAppId||g,p:!!n.refreshOnceOnNavigation}}(t),n.prototype.$meta=function(){return sn.call(this,t)},n.mixin(W(n,t)))},generate:function(n,t){return c("generate")},hasMetaInfo:x};export default dn; +import n from"deepmerge";function t(n){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n})(n)}function e(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e=n.length?{done:!0}:{done:!1,value:n[t++]}},e:function(n){throw n},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,o,a=!0,u=!1;return{s:function(){i=n[Symbol.iterator]()},n:function(){var n=i.next();return a=n.done,n},e:function(n){u=!0,o=n},f:function(){try{a||null==i.return||i.return()}finally{if(u)throw o}}}}function i(n){return Array.isArray(n)}function o(n){return void 0===n}function a(n){return"object"===t(n)}function u(n){return"object"===t(n)&&null!==n}function f(n){return"function"==typeof n}var c=(function(){try{return!o(window)}catch(n){return!1}}()?window:global).console||{};function s(n){c&&c.warn&&c.warn(n)}var d=function(n){return s("".concat(n," is not supported in browser builds"))},l={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},v="metaInfo",m="data-vue-meta",h="data-vue-meta-server-rendered",p="vmid",y="content",b="template",g=!0,w=10,A="ssr",I=Object.keys(l),T=[I[12],I[13]],N=[I[1],I[2],"changed"].concat(T),O=[I[3],I[4],I[5]],S=["link","style","script"],k=["once","skip","template"],M=["body","pbody"],j=["allowfullscreen","amp","amp-boilerplate","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"],K=null;function _(n,t,e){var r=n.t;t._vueMeta.i||!t._vueMeta.o&&"watcher"!==e||(t._vueMeta.i=null),t._vueMeta.i&&!t._vueMeta.u&&function(n,t){if(!(t=void 0===t?10:t))return void n();clearTimeout(K),K=setTimeout((function(){n()}),t)}((function(){t.$meta().refresh()}),r)}function D(n,t,e){if(!Array.prototype.findIndex){for(var r=0;r/g,">"],[/"/g,'"'],[/'/g,"'"]];function q(n,t,e){e=e||[];var r={T:function(n){return e.reduce((function(n,t){return n.replace(t[0],t[1])}),n)}};return T.forEach((function(n,e){if(0===e)R(t,n);else if(1===e)for(var i in t[n])R(t[n],i);r[n]=t[n]})),function n(t,e,r,o){var a=e.m,f=r.T,c=void 0===f?function(n){return n}:f,s={};for(var d in t){var l=t[d];if(V(N,d))s[d]=l;else{var v=T[0];if(r[v]&&V(r[v],d))s[d]=l;else{var m=t[a];if(m&&(v=T[1],r[v]&&r[v][m]&&V(r[v][m],d)))s[d]=l;else if("string"==typeof l?s[d]=c(l):i(l)?s[d]=l.map((function(t){return u(t)?n(t,e,r,!0):c(t)})):u(l)?s[d]=n(l,e,r,!0):s[d]=l,o){var h=c(d);d!==h&&(s[h]=s[d],delete s[d])}}}}return s}(t,n,r)}function F(n,t,e,r){var i=n.component,a=n.k,u=n.M;return!0!==e&&!0!==t[a]&&(o(e)&&t[a]&&(e=t[a],t[a]=!0),e?(o(r)&&(r=t[u]),t[u]=f(e)?e.call(i,r):e.replace(/%s/g,r),!0):(delete t[a],!1))}var G=!1;function Q(t,e,r){return r=r||{},void 0===e.title&&delete e.title,O.forEach((function(n){if(e[n])for(var t in e[n])t in e[n]&&void 0===e[n][t]&&(V(j,t)&&!G&&(s("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),G=!0),delete e[n][t])})),n(t,e,{S:function(n,t){return function(n,t,e){var r=n.component,i=n.m,o=n.k,a=n.M,u=[];return t.length||e.length?(t.forEach((function(n,t){if(n[i]){var f=D(e,(function(t){return t[i]===n[i]})),c=e[f];if(-1!==f){if(a in c&&void 0===c[a]||"innerHTML"in c&&void 0===c.innerHTML)return u.push(n),void e.splice(f,1);if(null!==c[a]&&null!==c.innerHTML){var s=n[o];if(s){if(!c[o])return F({component:r,k:o,M:a},c,s),void(c.template=!0);c[a]||F({component:r,k:o,M:a},c,void 0,n[a])}}else e.splice(f,1)}else u.push(n)}else u.push(n)})),u.concat(e)):u}(r,n,t)}})}function X(n,t){return function n(t,e,r){if(r=r||{},e._inactive)return r;var i=(t=t||{}).A,u=e.$metaInfo,f=e.$options,c=e.$children;if(f[i]){var s=u||f[i];a(s)&&(r=Q(r,s,t))}c.length&&c.forEach((function(e){(function(n){return(n=n||this)&&!o(n._vueMeta)})(e)&&(r=n(t,e,r))}));return r}(n||{},t,l)}var Y=[];function Z(n,t,e,r){var i=n.m,o=!1;return e.forEach((function(n){n[i]&&n.callback&&(o=!0,function(n,t){1===arguments.length&&(t=n,n=""),Y.push([n,t])}("".concat(t,"[data-").concat(i,'="').concat(n[i],'"]'),n.callback))})),r&&o?nn():o}function nn(){var n;"complete"!==(n||document).readyState?document.onreadystatechange=function(){tn()}:tn()}function tn(n){Y.forEach((function(t){var e=t[0],r=t[1],i="".concat(e,'[onload="this.__vm_l=1"]'),o=[];n||(o=x(z(i))),n&&n.matches(i)&&(o=[n]),o.forEach((function(n){if(!n.__vm_cb){var t=function(){n.__vm_cb=!0,W(n,"onload"),r(n)};n.__vm_l?t():n.__vm_ev||(n.__vm_ev=!0,n.addEventListener("load",t))}}))}))}var en,rn={};function on(n,t,e,r,i){var o=(t||{}).v,a=i.getAttribute(o);a&&(rn[e]=JSON.parse(decodeURI(a)),W(i,o));var u=rn[e]||{},f=[];for(var c in u)void 0!==u[c]&&n in u[c]&&(f.push(c),r[c]||delete u[c][n]);for(var s in r){var d=u[s];d&&d[n]===r[s]||(f.push(s),void 0!==r[s]&&(u[s]=u[s]||{},u[s][n]=r[s]))}for(var l=0,v=f;l1){var v=[];r=r.filter((function(n){var t=JSON.stringify(n),e=!V(v,t);return v.push(t),e}))}r.forEach((function(t){if(!t.skip){var r=document.createElement(e);t.once||r.setAttribute(u,n),Object.keys(t).forEach((function(n){if(!V(k,n))if("innerHTML"!==n)if("json"!==n)if("cssText"!==n)if("callback"!==n){var e=V(c,n)?"data-".concat(n):n,i=V(j,n);if(!i||t[n]){var o=i?"":t[n];r.setAttribute(e,o)}}else r.onload=function(){return t[n](r)};else r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText));else r.innerHTML=JSON.stringify(t.json);else r.innerHTML=t.innerHTML}));var i,o=l[function(n){var t=n.body,e=n.pbody;return t?"body":e?"pbody":"head"}(t)];o.some((function(n,t){return i=t,r.isEqualNode(n)}))&&(i||0===i)?o.splice(i,1):s.push(r)}}));var m=[];for(var h in l)Array.prototype.push.apply(m,l[h]);return m.forEach((function(n){n.parentNode.removeChild(n)})),s.forEach((function(n){n.hasAttribute("data-body")?o.appendChild(n):n.hasAttribute("data-pbody")?o.insertBefore(n,o.firstChild):i.appendChild(n)})),{oldTags:m,newTags:s}}function un(n,t,e){var r=t=t||{},o=r.g,a=r.j,u={},f=C(u,"html");if(n===a&&f.hasAttribute(o)){W(f,o);var c=!1;return S.forEach((function(n){e[n]&&Z(t,n,e[n])&&(c=!0)})),c&&nn(),!1}var s,d={},l={};for(var v in e)if(!V(N,v))if("title"!==v){if(V(O,v)){var m=v.substr(0,4);on(n,t,v,e[v],C(u,m))}else if(i(e[v])){var h=an(n,t,v,e[v],C(u,"head"),C(u,"body")),p=h.oldTags,y=h.newTags;y.length&&(d[v]=y,l[v]=p)}}else((s=e.title)||""===s)&&(document.title=s);return{D:d,K:l}}function fn(n,t,e){return{set:function(r){return function(n,t,e,r){if(n&&n.$el)return un(t,e,r);(en=en||{})[t]=r}(n,t,e,r)},remove:function(){return function(n,t,e){if(n&&n.$el){var i,o={},a=r(O);try{for(a.s();!(i=a.n()).done;){var u=i.value,f=u.substr(0,4);on(t,e,u,{},C(o,f))}}catch(n){a.e(n)}finally{a.f()}return function(n,t){var e=n.v;x(z("[".concat(e,'="').concat(t,'"]'))).map((function(n){return n.remove()}))}(e,t)}en[t]&&(delete en[t],sn())}(n,t,e)}}}function cn(){return en}function sn(n){!n&&Object.keys(en).length||(en=void 0)}function dn(n,t){if(t=t||{},!n._vueMeta)return s("This vue app/component has no vue-meta configuration"),{};var e=function(n,t,e,r){e=e||[];var i=(n=n||{}).m;return t.title&&(t.titleChunk=t.title),t.titleTemplate&&"%s"!==t.titleTemplate&&F({component:r,M:"title"},t,t.titleTemplate,t.titleChunk||""),t.base&&(t.base=Object.keys(t.base).length?[t.base]:[]),t.meta&&(t.meta=t.meta.filter((function(n,t,e){return!n[i]||t===D(e,(function(t){return t[i]===n[i]}))})),t.meta.forEach((function(t){return F(n,t)}))),q(n,t,e)}(t,X(t,n),U,n),r=un(n._vueMeta.l,t,e);r&&f(e.changed)&&(e.changed(e,r.D,r.K),r={addedTags:r.D,removedTags:r.K});var i=cn();if(i){for(var o in i)un(o,t,i[o]),delete i[o];sn(!0)}return{vm:n,metaInfo:e,tags:r}}function ln(n){n=n||{};var t=this.$root;return{getOptions:function(){return function(n){var t={};for(var e in n)t[e]=n[e];return t}(n)},setOptions:function(e){e&&e.I&&(n.I=!!e.I,H(t));if(e&&"debounceWait"in e){var r=parseInt(e.t);isNaN(r)||(n.t=r)}e&&"waitOnDestroyed"in e&&(n.O=!!e.O)},refresh:function(){return dn(t,n)},inject:function(){return d("inject")},pause:function(){return B(t)},resume:function(){return E(t)},addApp:function(e){return fn(t,e,n)}}}function vn(n,t){n.__vuemeta_installed||(n.__vuemeta_installed=!0,t=function(n){return{A:(n=a(n)?n:{}).keyName||v,v:n.attribute||m,g:n.ssrAttribute||h,m:n.tagIDKeyName||p,M:n.contentKeyName||y,k:n.metaTemplateKeyName||b,t:o(n.debounceWait)?w:n.debounceWait,O:o(n.waitOnDestroyed)?g:n.waitOnDestroyed,j:n.ssrAppId||A,I:!!n.refreshOnceOnNavigation}}(t),n.prototype.$meta=function(){return ln.call(this,t)},n.mixin(P(n,t)))}o(window)||o(window.Vue)||vn(window.Vue);var mn={version:"2.3.4",install:vn,generate:function(n,t){return d("generate")},hasMetaInfo:$};export default mn; diff --git a/dist/vue-meta.esm.js b/dist/vue-meta.esm.js index 7b24202..6b3cc9b 100644 --- a/dist/vue-meta.esm.js +++ b/dist/vue-meta.esm.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.3.3 + * vue-meta v2.3.4 * (c) 2020 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -10,7 +10,7 @@ import deepmerge from 'deepmerge'; -var version = "2.3.3"; +var version = "2.3.4"; function _typeof(obj) { "@babel/helpers - typeof"; @@ -78,23 +78,91 @@ function _objectSpread2(target) { } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(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; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); +} + +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); +} + +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +function _createForOfIteratorHelper(o) { + if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { + var i = 0; + + var F = function () {}; + + return { + s: F, + n: function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }, + e: function (e) { + throw e; + }, + f: F + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var it, + normalCompletion = true, + didErr = false, + err; + return { + s: function () { + it = o[Symbol.iterator](); + }, + n: function () { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e: function (e) { + didErr = true; + err = e; + }, + f: function () { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; } /** @@ -222,7 +290,7 @@ var tagProperties = ['once', 'skip', 'template']; // Attributes which should be var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 -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']; +var booleanHtmlAttributes = ['allowfullscreen', 'amp', 'amp-boilerplate', '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 batchId = null; function triggerUpdate(_ref, rootVm, hookName) { @@ -323,6 +391,48 @@ function includes(array, value) { return array.includes(value); } +var querySelector = function querySelector(arg, el) { + return (el || document).querySelectorAll(arg); +}; +function getTag(tags, tag) { + if (!tags[tag]) { + tags[tag] = document.getElementsByTagName(tag)[0]; + } + + return tags[tag]; +} +function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; + return body ? 'body' : pbody ? 'pbody' : 'head'; +} +function queryElements(parentNode, _ref2, attributes) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + attributes = attributes || {}; + 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 toArray(querySelector(queries.join(', '), parentNode)); +} +function removeElementsByAppId(_ref3, appId) { + var attribute = _ref3.attribute; + toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { + return el.remove(); + }); +} +function removeAttribute(el, attributeName) { + el.removeAttribute(attributeName); +} + function hasMetaInfo(vm) { vm = vm || this; return vm && (vm[rootConfigKey] === true || isObject(vm[rootConfigKey])); @@ -375,7 +485,8 @@ function addNavGuards(rootVm) { var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; + var wasServerRendered = false; // watch for client side component updates return { beforeCreate: function beforeCreate() { @@ -396,10 +507,26 @@ function createMixin(Vue, options) { return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo + }); + + if (this === $root) { + $root.$once('hook:beforeMount', function () { + wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered'); // In most cases when you have a SSR app it will be the first app thats gonna be + // initiated, if we cant detect the data-server-rendered attribute from Vue but we + // do see our own ssrAttribute then _assume_ the Vue app with appId 1 is the ssr app + // attempted fix for #404 & #562, but we rly need to refactor how we pass appIds from + // ssr to the client + + if (!wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1) { + var htmlTag = getTag({}, 'html'); + wasServerRendered = htmlTag && htmlTag.hasAttribute(options.ssrAttribute); + } + }); + } // 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($options[options.keyName]) || $options[options.keyName] === null) { return; } @@ -469,10 +596,10 @@ function createMixin(Vue, options) { if (!$root[rootConfigKey].initializedSsr) { $root[rootConfigKey].initializedSsr = true; this.$on('hook:beforeMount', function () { - var $root = this; // if this Vue-app was server rendered, set the appId to 'ssr' + var $root = this[rootKey]; // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) { + if (wasServerRendered) { $root[rootConfigKey].appId = options.ssrAppId; } }); @@ -482,37 +609,39 @@ function createMixin(Vue, options) { this.$on('hook:mounted', function () { var $root = this[rootKey]; - if (!$root[rootConfigKey].initialized) { - // used in triggerUpdate to check if a change was triggered - // during initialization - $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - - this.$nextTick(function () { - var _$root$$meta$refresh = $root.$meta().refresh(), - tags = _$root$$meta$refresh.tags, - metaInfo = _$root$$meta$refresh.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 ($root[rootConfigKey].initialized) { + return; + } // used in triggerUpdate to check if a change was triggered + // during initialization - if (tags === false && $root[rootConfigKey].initialized === null) { - this.$nextTick(function () { - return triggerUpdate(options, $root, 'init'); - }); - } + $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - $root[rootConfigKey].initialized = true; - delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet - // they are needed for the afterNavigation callback + this.$nextTick(function () { + var _$root$$meta$refresh = $root.$meta().refresh(), + tags = _$root$$meta$refresh.tags, + metaInfo = _$root$$meta$refresh.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 (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { - addNavGuards($root); - } - }); - } + + if (tags === false && $root[rootConfigKey].initialized === null) { + this.$nextTick(function () { + return triggerUpdate(options, $root, 'init'); + }); + } + + $root[rootConfigKey].initialized = true; + delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet + // they are needed for the afterNavigation callback + + if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { + addNavGuards($root); + } + }); }); // add the navigation guards if requested if (options.refreshOnceOnNavigation) { @@ -912,48 +1041,6 @@ function getComponentOption(options, component, result) { return result; } -var querySelector = function querySelector(arg, el) { - return (el || document).querySelectorAll(arg); -}; -function getTag(tags, tag) { - if (!tags[tag]) { - tags[tag] = document.getElementsByTagName(tag)[0]; - } - - return tags[tag]; -} -function getElementsKey(_ref) { - var body = _ref.body, - pbody = _ref.pbody; - return body ? 'body' : pbody ? 'pbody' : 'head'; -} -function queryElements(parentNode, _ref2, attributes) { - var appId = _ref2.appId, - attribute = _ref2.attribute, - type = _ref2.type, - tagIDKeyName = _ref2.tagIDKeyName; - attributes = attributes || {}; - 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 toArray(querySelector(queries.join(', '), parentNode)); -} -function removeElementsByAppId(_ref3, appId) { - var attribute = _ref3.attribute; - toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { - return el.remove(); - }); -} -function removeAttribute(el, attributeName) { - el.removeAttribute(attributeName); -} - var callbacks = []; function isDOMComplete(d) { return (d || document).readyState === 'complete'; @@ -1084,7 +1171,7 @@ function updateAttribute(appId, options, type, attrs, tag) { // which have been removed for this appId for (var attr in data) { - if (data[attr] && appId in data[attr]) { + if (data[attr] !== undefined && appId in data[attr]) { toUpdate.push(attr); if (!attrs[attr]) { @@ -1099,7 +1186,7 @@ function updateAttribute(appId, options, type, attrs, tag) { if (!attrData || attrData[appId] !== attrs[_attr]) { toUpdate.push(_attr); - if (attrs[_attr]) { + if (attrs[_attr] !== undefined) { data[_attr] = data[_attr] || {}; data[_attr][appId] = attrs[_attr]; } @@ -1116,7 +1203,9 @@ function updateAttribute(appId, options, type, attrs, tag) { } if (attrValues.length) { - var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(Boolean).join(' '); + var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(function (v) { + return v !== undefined; + }).join(' '); tag.setAttribute(_attr2, attrValue); } else { removeAttribute(tag, _attr2); @@ -1387,29 +1476,20 @@ function setMetaInfo(rootVm, appId, options, metaInfo) { function removeMetaInfo(rootVm, appId, options) { if (rootVm && rootVm.$el) { var tags = {}; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + + var _iterator = _createForOfIteratorHelper(metaInfoAttributeKeys), + _step; try { - for (var _iterator = metaInfoAttributeKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var type = _step.value; var tagName = type.substr(0, 4); updateAttribute(appId, options, type, {}, getTag(tags, tagName)); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } return removeElementsByAppId(options, appId); @@ -1756,7 +1836,7 @@ function generateServerInjector(options, metaInfo) { if (_data) { for (var _attr in _data) { - attributeData[_attr] = _objectSpread2({}, attributeData[_attr], _defineProperty({}, appId, _data[_attr])); + attributeData[_attr] = _objectSpread2(_objectSpread2({}, attributeData[_attr]), {}, _defineProperty({}, appId, _data[_attr])); } } } diff --git a/dist/vue-meta.js b/dist/vue-meta.js index f568330..bf287d6 100644 --- a/dist/vue-meta.js +++ b/dist/vue-meta.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.3.3 + * vue-meta v2.3.4 * (c) 2020 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -14,7 +14,7 @@ (global = global || self, global.VueMeta = factory()); }(this, (function () { 'use strict'; - var version = "2.3.3"; + var version = "2.3.4"; function _typeof(obj) { "@babel/helpers - typeof"; @@ -32,6 +32,78 @@ return _typeof(obj); } + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; + } + + function _createForOfIteratorHelper(o) { + if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { + var i = 0; + + var F = function () {}; + + return { + s: F, + n: function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }, + e: function (e) { + throw e; + }, + f: F + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var it, + normalCompletion = true, + didErr = false, + err; + return { + s: function () { + it = o[Symbol.iterator](); + }, + n: function () { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e: function (e) { + didErr = true; + err = e; + }, + f: function () { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; + } + /** * checks if passed argument is an array * @param {any} arg - the object to check @@ -153,7 +225,7 @@ var commonDataAttributes = ['body', 'pbody']; // from: https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L202 - 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']; + var booleanHtmlAttributes = ['allowfullscreen', 'amp', 'amp-boilerplate', '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 batchId = null; function triggerUpdate(_ref, rootVm, hookName) { @@ -254,6 +326,48 @@ return array.includes(value); } + var querySelector = function querySelector(arg, el) { + return (el || document).querySelectorAll(arg); + }; + function getTag(tags, tag) { + if (!tags[tag]) { + tags[tag] = document.getElementsByTagName(tag)[0]; + } + + return tags[tag]; + } + function getElementsKey(_ref) { + var body = _ref.body, + pbody = _ref.pbody; + return body ? 'body' : pbody ? 'pbody' : 'head'; + } + function queryElements(parentNode, _ref2, attributes) { + var appId = _ref2.appId, + attribute = _ref2.attribute, + type = _ref2.type, + tagIDKeyName = _ref2.tagIDKeyName; + attributes = attributes || {}; + 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 toArray(querySelector(queries.join(', '), parentNode)); + } + function removeElementsByAppId(_ref3, appId) { + var attribute = _ref3.attribute; + toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { + return el.remove(); + }); + } + function removeAttribute(el, attributeName) { + el.removeAttribute(attributeName); + } + function hasMetaInfo(vm) { vm = vm || this; return vm && (vm[rootConfigKey] === true || isObject(vm[rootConfigKey])); @@ -306,7 +420,8 @@ var appId = 1; function createMixin(Vue, options) { // for which Vue lifecycle hooks should the metaInfo be refreshed - var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; // watch for client side component updates + var updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']; + var wasServerRendered = false; // watch for client side component updates return { beforeCreate: function beforeCreate() { @@ -327,10 +442,26 @@ return hasMetaInfo(this); } - }); // Add a marker to know if it uses metaInfo + }); + + if (this === $root) { + $root.$once('hook:beforeMount', function () { + wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered'); // In most cases when you have a SSR app it will be the first app thats gonna be + // initiated, if we cant detect the data-server-rendered attribute from Vue but we + // do see our own ssrAttribute then _assume_ the Vue app with appId 1 is the ssr app + // attempted fix for #404 & #562, but we rly need to refactor how we pass appIds from + // ssr to the client + + if (!wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1) { + var htmlTag = getTag({}, 'html'); + wasServerRendered = htmlTag && htmlTag.hasAttribute(options.ssrAttribute); + } + }); + } // 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($options[options.keyName]) || $options[options.keyName] === null) { return; } @@ -400,10 +531,10 @@ if (!$root[rootConfigKey].initializedSsr) { $root[rootConfigKey].initializedSsr = true; this.$on('hook:beforeMount', function () { - var $root = this; // if this Vue-app was server rendered, set the appId to 'ssr' + var $root = this[rootKey]; // if this Vue-app was server rendered, set the appId to 'ssr' // only one SSR app per page is supported - if ($root.$el && $root.$el.nodeType === 1 && $root.$el.hasAttribute('data-server-rendered')) { + if (wasServerRendered) { $root[rootConfigKey].appId = options.ssrAppId; } }); @@ -413,37 +544,39 @@ this.$on('hook:mounted', function () { var $root = this[rootKey]; - if (!$root[rootConfigKey].initialized) { - // used in triggerUpdate to check if a change was triggered - // during initialization - $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - - this.$nextTick(function () { - var _$root$$meta$refresh = $root.$meta().refresh(), - tags = _$root$$meta$refresh.tags, - metaInfo = _$root$$meta$refresh.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 ($root[rootConfigKey].initialized) { + return; + } // used in triggerUpdate to check if a change was triggered + // during initialization - if (tags === false && $root[rootConfigKey].initialized === null) { - this.$nextTick(function () { - return triggerUpdate(options, $root, 'init'); - }); - } + $root[rootConfigKey].initializing = true; // refresh meta in nextTick so all child components have loaded - $root[rootConfigKey].initialized = true; - delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet - // they are needed for the afterNavigation callback + this.$nextTick(function () { + var _$root$$meta$refresh = $root.$meta().refresh(), + tags = _$root$$meta$refresh.tags, + metaInfo = _$root$$meta$refresh.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 (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { - addNavGuards($root); - } - }); - } + + if (tags === false && $root[rootConfigKey].initialized === null) { + this.$nextTick(function () { + return triggerUpdate(options, $root, 'init'); + }); + } + + $root[rootConfigKey].initialized = true; + delete $root[rootConfigKey].initializing; // add the navigation guards if they havent been added yet + // they are needed for the afterNavigation callback + + if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) { + addNavGuards($root); + } + }); }); // add the navigation guards if requested if (options.refreshOnceOnNavigation) { @@ -929,48 +1062,6 @@ return result; } - var querySelector = function querySelector(arg, el) { - return (el || document).querySelectorAll(arg); - }; - function getTag(tags, tag) { - if (!tags[tag]) { - tags[tag] = document.getElementsByTagName(tag)[0]; - } - - return tags[tag]; - } - function getElementsKey(_ref) { - var body = _ref.body, - pbody = _ref.pbody; - return body ? 'body' : pbody ? 'pbody' : 'head'; - } - function queryElements(parentNode, _ref2, attributes) { - var appId = _ref2.appId, - attribute = _ref2.attribute, - type = _ref2.type, - tagIDKeyName = _ref2.tagIDKeyName; - attributes = attributes || {}; - 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 toArray(querySelector(queries.join(', '), parentNode)); - } - function removeElementsByAppId(_ref3, appId) { - var attribute = _ref3.attribute; - toArray(querySelector("[".concat(attribute, "=\"").concat(appId, "\"]"))).map(function (el) { - return el.remove(); - }); - } - function removeAttribute(el, attributeName) { - el.removeAttribute(attributeName); - } - var callbacks = []; function isDOMComplete(d) { return (d || document).readyState === 'complete'; @@ -1101,7 +1192,7 @@ // which have been removed for this appId for (var attr in data) { - if (data[attr] && appId in data[attr]) { + if (data[attr] !== undefined && appId in data[attr]) { toUpdate.push(attr); if (!attrs[attr]) { @@ -1116,7 +1207,7 @@ if (!attrData || attrData[appId] !== attrs[_attr]) { toUpdate.push(_attr); - if (attrs[_attr]) { + if (attrs[_attr] !== undefined) { data[_attr] = data[_attr] || {}; data[_attr][appId] = attrs[_attr]; } @@ -1133,7 +1224,9 @@ } if (attrValues.length) { - var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(Boolean).join(' '); + var attrValue = includes(booleanHtmlAttributes, _attr2) && attrValues.some(Boolean) ? '' : attrValues.filter(function (v) { + return v !== undefined; + }).join(' '); tag.setAttribute(_attr2, attrValue); } else { removeAttribute(tag, _attr2); @@ -1404,29 +1497,20 @@ function removeMetaInfo(rootVm, appId, options) { if (rootVm && rootVm.$el) { var tags = {}; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + + var _iterator = _createForOfIteratorHelper(metaInfoAttributeKeys), + _step; try { - for (var _iterator = metaInfoAttributeKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var type = _step.value; var tagName = type.substr(0, 4); updateAttribute(appId, options, type, {}, getTag(tags, tagName)); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } return removeElementsByAppId(options, appId); @@ -1629,6 +1713,14 @@ Vue.mixin(createMixin(Vue, options)); } + { + // automatic install + if (!isUndefined(window) && !isUndefined(window.Vue)) { + /* istanbul ignore next */ + install(window.Vue); + } + } + var index = { version: version, install: install, diff --git a/dist/vue-meta.min.js b/dist/vue-meta.min.js index eca9c49..bba9a46 100644 --- a/dist/vue-meta.min.js +++ b/dist/vue-meta.min.js @@ -1,5 +1,5 @@ /** - * vue-meta v2.3.3 + * vue-meta v2.3.4 * (c) 2020 * - Declan de Wet * - Sébastien Chopin (@Atinux) @@ -7,4 +7,4 @@ * - All the amazing contributors * @license MIT */ -!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n=n||self).VueMeta=t()}(this,(function(){"use strict";function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n})(t)}function t(n){return Array.isArray(n)}function e(n){return void 0===n}function r(t){return"object"===n(t)}function i(t){return"object"===n(t)&&null!==t}function o(n){return"function"==typeof n}var u=(function(){try{return!e(window)}catch(n){return!1}}()?window:global).console||{};function a(n){u&&u.warn&&u.warn(n)}var f=function(n){return a("".concat(n," is not supported in browser builds"))},c={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},s="metaInfo",d="data-vue-meta",l="data-vue-meta-server-rendered",v="vmid",m="content",h="template",y=!0,p=10,b="ssr",g=Object.keys(c),A=[g[12],g[13]],j=[g[1],g[2],"changed"].concat(A),I=[g[3],g[4],g[5]],O=["link","style","script"],N=["once","skip","template"],T=["body","pbody"],w=["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"],k=null;function M(n,t,e){var r=n.t;t._vueMeta.i||!t._vueMeta.o&&"watcher"!==e||(t._vueMeta.i=null),t._vueMeta.i&&!t._vueMeta.u&&function(n,t){if(!(t=void 0===t?10:t))return void n();clearTimeout(k),k=setTimeout((function(){n()}),t)}((function(){t.$meta().refresh()}),r)}function S(n,t,e){if(!Array.prototype.findIndex){for(var r=0;r/g,">"],[/"/g,'"'],[/'/g,"'"]];function C(n,e,r){r=r||[];var o={A:function(n){return r.reduce((function(n,t){return n.replace(t[0],t[1])}),n)}};return A.forEach((function(n,t){if(0===t)R(e,n);else if(1===t)for(var r in e[n])R(e[n],r);o[n]=e[n]})),function n(e,r,o,u){var a=r.j,f=o.A,c=void 0===f?function(n){return n}:f,s={};for(var d in e){var l=e[d];if(K(j,d))s[d]=l;else{var v=A[0];if(o[v]&&K(o[v],d))s[d]=l;else{var m=e[a];if(m&&(v=A[1],o[v]&&o[v][m]&&K(o[v][m],d)))s[d]=l;else if("string"==typeof l?s[d]=c(l):t(l)?s[d]=l.map((function(t){return i(t)?n(t,r,o,!0):c(t)})):i(l)?s[d]=n(l,r,o,!0):s[d]=l,u){var h=c(d);d!==h&&(s[h]=s[d],delete s[d])}}}}return s}(e,n,o)}var E=function(t){return function(t){return!!t&&"object"===n(t)}(t)&&!function(n){var t=Object.prototype.toString.call(n);return"[object RegExp]"===t||"[object Date]"===t||!1}(t)};function H(n,t){return n}function L(n){return Object.keys(n)}function P(n,t){try{return t in n}catch(n){return!1}}function $(n,t,e){var r={};return e.I(n)&&L(n).forEach((function(t){r[t]=H(n[t])})),L(t).forEach((function(i){(function(n,t){return P(n,t)&&!(Object.hasOwnProperty.call(n,t)&&Object.propertyIsEnumerable.call(n,t))})(n,i)||(P(n,i)&&e.I(t[i])?r[i]=q(n[i],t[i],e):r[i]=H(t[i]))})),r}function q(n,t,e){(e=e||{}).O=e.O,e.I=e.I||E,e.cloneUnlessOtherwiseSpecified=H;var r=Array.isArray(t);return r===Array.isArray(n)?r?e.O(n,t,e):$(n,t,e):H(t)}var U=q;function F(n,t,r,i){var u=n.component,a=n.N,f=n.T;return!0!==r&&!0!==t[a]&&(e(r)&&t[a]&&(r=t[a],t[a]=!0),r?(e(i)&&(i=t[f]),t[f]=o(r)?r.call(u,i):r.replace(/%s/g,i),!0):(delete t[a],!1))}var G=!1;function Q(n,t,e){return e=e||{},void 0===t.title&&delete t.title,I.forEach((function(n){if(t[n])for(var e in t[n])e in t[n]&&void 0===t[n][e]&&(K(w,e)&&!G&&(a("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),G=!0),delete t[n][e])})),U(n,t,{O:function(n,t){return function(n,t,e){var r=n.component,i=n.j,o=n.N,u=n.T,a=[];return t.length||e.length?(t.forEach((function(n,t){if(n[i]){var f=S(e,(function(t){return t[i]===n[i]})),c=e[f];if(-1!==f){if(u in c&&void 0===c[u]||"innerHTML"in c&&void 0===c.innerHTML)return a.push(n),void e.splice(f,1);if(null!==c[u]&&null!==c.innerHTML){var s=n[o];if(s){if(!c[o])return F({component:r,N:o,T:u},c,s),void(c.template=!0);c[u]||F({component:r,N:o,T:u},c,void 0,n[u])}}else e.splice(f,1)}else a.push(n)}else a.push(n)})),a.concat(e)):a}(e,n,t)}})}function X(n,t){return function n(t,i,o){if(o=o||{},i._inactive)return o;var u=(t=t||{}).v,a=i.$metaInfo,f=i.$options,c=i.$children;if(f[u]){var s=a||f[u];r(s)&&(o=Q(o,s,t))}c.length&&c.forEach((function(r){(function(n){return(n=n||this)&&!e(n._vueMeta)})(r)&&(o=n(t,r,o))}));return o}(n||{},t,c)}var Y=function(n,t){return(t||document).querySelectorAll(n)};function Z(n,t){return n[t]||(n[t]=document.getElementsByTagName(t)[0]),n[t]}function nn(n,t,e){var r=t.m,i=t.k,o=t.type,u=t.j;e=e||{};var a=["".concat(o,"[").concat(i,'="').concat(r,'"]'),"".concat(o,"[data-").concat(u,"]")].map((function(n){for(var t in e){var r=e[t],i=r&&!0!==r?'="'.concat(r,'"'):"";n+="[data-".concat(t).concat(i,"]")}return n}));return D(Y(a.join(", "),n))}function tn(n,t){n.removeAttribute(t)}var en=[];function rn(n,t,e,r){var i=n.j,o=!1;return e.forEach((function(n){n[i]&&n.callback&&(o=!0,function(n,t){1===arguments.length&&(t=n,n=""),en.push([n,t])}("".concat(t,"[data-").concat(i,'="').concat(n[i],'"]'),n.callback))})),r&&o?on():o}function on(){var n;"complete"!==(n||document).readyState?document.onreadystatechange=function(){un()}:un()}function un(n){en.forEach((function(t){var e=t[0],r=t[1],i="".concat(e,'[onload="this.__vm_l=1"]'),o=[];n||(o=D(Y(i))),n&&n.matches(i)&&(o=[n]),o.forEach((function(n){if(!n.__vm_cb){var t=function(){n.__vm_cb=!0,tn(n,"onload"),r(n)};n.__vm_l?t():n.__vm_ev||(n.__vm_ev=!0,n.addEventListener("load",t))}}))}))}var an,fn={};function cn(n,t,e,r,i){var o=(t||{}).k,u=i.getAttribute(o);u&&(fn[e]=JSON.parse(decodeURI(u)),tn(i,o));var a=fn[e]||{},f=[];for(var c in a)a[c]&&n in a[c]&&(f.push(c),r[c]||delete a[c][n]);for(var s in r){var d=a[s];d&&d[n]===r[s]||(f.push(s),r[s]&&(a[s]=a[s]||{},a[s][n]=r[s]))}for(var l=0,v=f;l1){var v=[];r=r.filter((function(n){var t=JSON.stringify(n),e=!K(v,t);return v.push(t),e}))}r.forEach((function(t){if(!t.skip){var r=document.createElement(e);t.once||r.setAttribute(a,n),Object.keys(t).forEach((function(n){if(!K(N,n))if("innerHTML"!==n)if("json"!==n)if("cssText"!==n)if("callback"!==n){var e=K(c,n)?"data-".concat(n):n,i=K(w,n);if(!i||t[n]){var o=i?"":t[n];r.setAttribute(e,o)}}else r.onload=function(){return t[n](r)};else r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText));else r.innerHTML=JSON.stringify(t.json);else r.innerHTML=t.innerHTML}));var i,o=l[function(n){var t=n.body,e=n.pbody;return t?"body":e?"pbody":"head"}(t)];o.some((function(n,t){return i=t,r.isEqualNode(n)}))&&(i||0===i)?o.splice(i,1):s.push(r)}}));var m=[];for(var h in l)Array.prototype.push.apply(m,l[h]);return m.forEach((function(n){n.parentNode.removeChild(n)})),s.forEach((function(n){n.hasAttribute("data-body")?o.appendChild(n):n.hasAttribute("data-pbody")?o.insertBefore(n,o.firstChild):i.appendChild(n)})),{oldTags:m,newTags:s}}function dn(n,e,r){var i=e=e||{},o=i.M,u=i.h,a={},f=Z(a,"html");if(n===u&&f.hasAttribute(o)){tn(f,o);var c=!1;return O.forEach((function(n){r[n]&&rn(e,n,r[n])&&(c=!0)})),c&&on(),!1}var s,d={},l={};for(var v in r)if(!K(j,v))if("title"!==v){if(K(I,v)){var m=v.substr(0,4);cn(n,e,v,r[v],Z(a,m))}else if(t(r[v])){var h=sn(n,e,v,r[v],Z(a,"head"),Z(a,"body")),y=h.oldTags,p=h.newTags;p.length&&(d[v]=p,l[v]=y)}}else((s=r.title)||""===s)&&(document.title=s);return{S:d,D:l}}function ln(n,t,e){return{set:function(r){return function(n,t,e,r){if(n&&n.$el)return dn(t,e,r);(an=an||{})[t]=r}(n,t,e,r)},remove:function(){return function(n,t,e){if(n&&n.$el){var r={},i=!0,o=!1,u=void 0;try{for(var a,f=I[Symbol.iterator]();!(i=(a=f.next()).done);i=!0){var c=a.value,s=c.substr(0,4);cn(t,e,c,{},Z(r,s))}}catch(n){o=!0,u=n}finally{try{i||null==f.return||f.return()}finally{if(o)throw u}}return function(n,t){var e=n.k;D(Y("[".concat(e,'="').concat(t,'"]'))).map((function(n){return n.remove()}))}(e,t)}an[t]&&(delete an[t],mn())}(n,t,e)}}}function vn(){return an}function mn(n){!n&&Object.keys(an).length||(an=void 0)}function hn(n,t){if(t=t||{},!n._vueMeta)return a("This vue app/component has no vue-meta configuration"),{};var e=function(n,t,e,r){e=e||[];var i=(n=n||{}).j;return t.title&&(t.titleChunk=t.title),t.titleTemplate&&"%s"!==t.titleTemplate&&F({component:r,T:"title"},t,t.titleTemplate,t.titleChunk||""),t.base&&(t.base=Object.keys(t.base).length?[t.base]:[]),t.meta&&(t.meta=t.meta.filter((function(n,t,e){return!n[i]||t===S(e,(function(t){return t[i]===n[i]}))})),t.meta.forEach((function(t){return F(n,t)}))),C(n,t,e)}(t,X(t,n),W,n),r=dn(n._vueMeta.m,t,e);r&&o(e.changed)&&(e.changed(e,r.S,r.D),r={addedTags:r.S,removedTags:r.D});var i=vn();if(i){for(var u in i)dn(u,t,i[u]),delete i[u];mn(!0)}return{vm:n,metaInfo:e,tags:r}}function yn(n){n=n||{};var t=this.$root;return{getOptions:function(){return function(n){var t={};for(var e in n)t[e]=n[e];return t}(n)},setOptions:function(e){e&&e.p&&(n.p=!!e.p,z(t));if(e&&"debounceWait"in e){var r=parseInt(e.t);isNaN(r)||(n.t=r)}e&&"waitOnDestroyed"in e&&(n.g=!!e.g)},refresh:function(){return hn(t,n)},inject:function(){return f("inject")},pause:function(){return x(t)},resume:function(){return V(t)},addApp:function(e){return ln(t,e,n)}}}return{version:"2.3.3",install:function(n,t){n.__vuemeta_installed||(n.__vuemeta_installed=!0,t=function(n){return{v:(n=r(n)?n:{}).keyName||s,k:n.attribute||d,M:n.ssrAttribute||l,j:n.tagIDKeyName||v,T:n.contentKeyName||m,N:n.metaTemplateKeyName||h,t:e(n.debounceWait)?p:n.debounceWait,g:e(n.waitOnDestroyed)?y:n.waitOnDestroyed,h:n.ssrAppId||b,p:!!n.refreshOnceOnNavigation}}(t),n.prototype.$meta=function(){return yn.call(this,t)},n.mixin(J(n,t)))},generate:function(n,t){return f("generate")},hasMetaInfo:_}})); +!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n=n||self).VueMeta=t()}(this,(function(){"use strict";function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n})(t)}function t(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e=n.length?{done:!0}:{done:!1,value:n[e++]}},e:function(n){throw n},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,o,u=!0,a=!1;return{s:function(){i=n[Symbol.iterator]()},n:function(){var n=i.next();return u=n.done,n},e:function(n){a=!0,o=n},f:function(){try{u||null==i.return||i.return()}finally{if(a)throw o}}}}function r(n){return Array.isArray(n)}function i(n){return void 0===n}function o(t){return"object"===n(t)}function u(t){return"object"===n(t)&&null!==t}function a(n){return"function"==typeof n}var f=(function(){try{return!i(window)}catch(n){return!1}}()?window:global).console||{};function c(n){f&&f.warn&&f.warn(n)}var s=function(n){return c("".concat(n," is not supported in browser builds"))},d={title:void 0,titleChunk:"",titleTemplate:"%s",htmlAttrs:{},bodyAttrs:{},headAttrs:{},base:[],link:[],meta:[],style:[],script:[],noscript:[],__dangerouslyDisableSanitizers:[],__dangerouslyDisableSanitizersByTagID:{}},l="metaInfo",v="data-vue-meta",m="data-vue-meta-server-rendered",y="vmid",h="content",p="template",b=!0,g=10,w="ssr",A=Object.keys(d),j=[A[12],A[13]],I=[A[1],A[2],"changed"].concat(j),O=[A[3],A[4],A[5]],T=["link","style","script"],N=["once","skip","template"],S=["body","pbody"],k=["allowfullscreen","amp","amp-boilerplate","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"],M=null;function D(n,t,e){var r=n.t;t._vueMeta.i||!t._vueMeta.o&&"watcher"!==e||(t._vueMeta.i=null),t._vueMeta.i&&!t._vueMeta.u&&function(n,t){if(!(t=void 0===t?10:t))return void n();clearTimeout(M),M=setTimeout((function(){n()}),t)}((function(){t.$meta().refresh()}),r)}function K(n,t,e){if(!Array.prototype.findIndex){for(var r=0;r/g,">"],[/"/g,'"'],[/'/g,"'"]];function U(n,t,e){e=e||[];var i={T:function(n){return e.reduce((function(n,t){return n.replace(t[0],t[1])}),n)}};return j.forEach((function(n,e){if(0===e)L(t,n);else if(1===e)for(var r in t[n])L(t[n],r);i[n]=t[n]})),function n(t,e,i,o){var a=e.m,f=i.T,c=void 0===f?function(n){return n}:f,s={};for(var d in t){var l=t[d];if(x(I,d))s[d]=l;else{var v=j[0];if(i[v]&&x(i[v],d))s[d]=l;else{var m=t[a];if(m&&(v=j[1],i[v]&&i[v][m]&&x(i[v][m],d)))s[d]=l;else if("string"==typeof l?s[d]=c(l):r(l)?s[d]=l.map((function(t){return u(t)?n(t,e,i,!0):c(t)})):u(l)?s[d]=n(l,e,i,!0):s[d]=l,o){var y=c(d);d!==y&&(s[y]=s[d],delete s[d])}}}}return s}(t,n,i)}var q=function(t){return function(t){return!!t&&"object"===n(t)}(t)&&!function(n){var t=Object.prototype.toString.call(n);return"[object RegExp]"===t||"[object Date]"===t||!1}(t)};function F(n,t){return n}function G(n){return Object.keys(n)}function Q(n,t){try{return t in n}catch(n){return!1}}function X(n,t,e){var r={};return e.N(n)&&G(n).forEach((function(t){r[t]=F(n[t])})),G(t).forEach((function(i){(function(n,t){return Q(n,t)&&!(Object.hasOwnProperty.call(n,t)&&Object.propertyIsEnumerable.call(n,t))})(n,i)||(Q(n,i)&&e.N(t[i])?r[i]=Y(n[i],t[i],e):r[i]=F(t[i]))})),r}function Y(n,t,e){(e=e||{}).S=e.S,e.N=e.N||q,e.cloneUnlessOtherwiseSpecified=F;var r=Array.isArray(t);return r===Array.isArray(n)?r?e.S(n,t,e):X(n,t,e):F(t)}var Z=Y;function nn(n,t,e,r){var o=n.component,u=n.k,f=n.M;return!0!==e&&!0!==t[u]&&(i(e)&&t[u]&&(e=t[u],t[u]=!0),e?(i(r)&&(r=t[f]),t[f]=a(e)?e.call(o,r):e.replace(/%s/g,r),!0):(delete t[u],!1))}var tn=!1;function en(n,t,e){return e=e||{},void 0===t.title&&delete t.title,O.forEach((function(n){if(t[n])for(var e in t[n])e in t[n]&&void 0===t[n][e]&&(x(k,e)&&!tn&&(c("VueMeta: Please note that since v2 the value undefined is not used to indicate boolean attributes anymore, see migration guide for details"),tn=!0),delete t[n][e])})),Z(n,t,{S:function(n,t){return function(n,t,e){var r=n.component,i=n.m,o=n.k,u=n.M,a=[];return t.length||e.length?(t.forEach((function(n,t){if(n[i]){var f=K(e,(function(t){return t[i]===n[i]})),c=e[f];if(-1!==f){if(u in c&&void 0===c[u]||"innerHTML"in c&&void 0===c.innerHTML)return a.push(n),void e.splice(f,1);if(null!==c[u]&&null!==c.innerHTML){var s=n[o];if(s){if(!c[o])return nn({component:r,k:o,M:u},c,s),void(c.template=!0);c[u]||nn({component:r,k:o,M:u},c,void 0,n[u])}}else e.splice(f,1)}else a.push(n)}else a.push(n)})),a.concat(e)):a}(e,n,t)}})}function rn(n,t){return function n(t,e,r){if(r=r||{},e._inactive)return r;var u=(t=t||{}).A,a=e.$metaInfo,f=e.$options,c=e.$children;if(f[u]){var s=a||f[u];o(s)&&(r=en(r,s,t))}c.length&&c.forEach((function(e){(function(n){return(n=n||this)&&!i(n._vueMeta)})(e)&&(r=n(t,e,r))}));return r}(n||{},t,d)}var on=[];function un(n,t,e,r){var i=n.m,o=!1;return e.forEach((function(n){n[i]&&n.callback&&(o=!0,function(n,t){1===arguments.length&&(t=n,n=""),on.push([n,t])}("".concat(t,"[data-").concat(i,'="').concat(n[i],'"]'),n.callback))})),r&&o?an():o}function an(){var n;"complete"!==(n||document).readyState?document.onreadystatechange=function(){fn()}:fn()}function fn(n){on.forEach((function(t){var e=t[0],r=t[1],i="".concat(e,'[onload="this.__vm_l=1"]'),o=[];n||(o=_(V(i))),n&&n.matches(i)&&(o=[n]),o.forEach((function(n){if(!n.__vm_cb){var t=function(){n.__vm_cb=!0,E(n,"onload"),r(n)};n.__vm_l?t():n.__vm_ev||(n.__vm_ev=!0,n.addEventListener("load",t))}}))}))}var cn,sn={};function dn(n,t,e,r,i){var o=(t||{}).v,u=i.getAttribute(o);u&&(sn[e]=JSON.parse(decodeURI(u)),E(i,o));var a=sn[e]||{},f=[];for(var c in a)void 0!==a[c]&&n in a[c]&&(f.push(c),r[c]||delete a[c][n]);for(var s in r){var d=a[s];d&&d[n]===r[s]||(f.push(s),void 0!==r[s]&&(a[s]=a[s]||{},a[s][n]=r[s]))}for(var l=0,v=f;l1){var v=[];r=r.filter((function(n){var t=JSON.stringify(n),e=!x(v,t);return v.push(t),e}))}r.forEach((function(t){if(!t.skip){var r=document.createElement(e);t.once||r.setAttribute(a,n),Object.keys(t).forEach((function(n){if(!x(N,n))if("innerHTML"!==n)if("json"!==n)if("cssText"!==n)if("callback"!==n){var e=x(c,n)?"data-".concat(n):n,i=x(k,n);if(!i||t[n]){var o=i?"":t[n];r.setAttribute(e,o)}}else r.onload=function(){return t[n](r)};else r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText));else r.innerHTML=JSON.stringify(t.json);else r.innerHTML=t.innerHTML}));var i,o=l[function(n){var t=n.body,e=n.pbody;return t?"body":e?"pbody":"head"}(t)];o.some((function(n,t){return i=t,r.isEqualNode(n)}))&&(i||0===i)?o.splice(i,1):s.push(r)}}));var m=[];for(var y in l)Array.prototype.push.apply(m,l[y]);return m.forEach((function(n){n.parentNode.removeChild(n)})),s.forEach((function(n){n.hasAttribute("data-body")?o.appendChild(n):n.hasAttribute("data-pbody")?o.insertBefore(n,o.firstChild):i.appendChild(n)})),{oldTags:m,newTags:s}}function vn(n,t,e){var i=t=t||{},o=i.g,u=i.j,a={},f=z(a,"html");if(n===u&&f.hasAttribute(o)){E(f,o);var c=!1;return T.forEach((function(n){e[n]&&un(t,n,e[n])&&(c=!0)})),c&&an(),!1}var s,d={},l={};for(var v in e)if(!x(I,v))if("title"!==v){if(x(O,v)){var m=v.substr(0,4);dn(n,t,v,e[v],z(a,m))}else if(r(e[v])){var y=ln(n,t,v,e[v],z(a,"head"),z(a,"body")),h=y.oldTags,p=y.newTags;p.length&&(d[v]=p,l[v]=h)}}else((s=e.title)||""===s)&&(document.title=s);return{D:d,K:l}}function mn(n,t,r){return{set:function(e){return function(n,t,e,r){if(n&&n.$el)return vn(t,e,r);(cn=cn||{})[t]=r}(n,t,r,e)},remove:function(){return function(n,t,r){if(n&&n.$el){var i,o={},u=e(O);try{for(u.s();!(i=u.n()).done;){var a=i.value,f=a.substr(0,4);dn(t,r,a,{},z(o,f))}}catch(n){u.e(n)}finally{u.f()}return function(n,t){var e=n.v;_(V("[".concat(e,'="').concat(t,'"]'))).map((function(n){return n.remove()}))}(r,t)}cn[t]&&(delete cn[t],hn())}(n,t,r)}}}function yn(){return cn}function hn(n){!n&&Object.keys(cn).length||(cn=void 0)}function pn(n,t){if(t=t||{},!n._vueMeta)return c("This vue app/component has no vue-meta configuration"),{};var e=function(n,t,e,r){e=e||[];var i=(n=n||{}).m;return t.title&&(t.titleChunk=t.title),t.titleTemplate&&"%s"!==t.titleTemplate&&nn({component:r,M:"title"},t,t.titleTemplate,t.titleChunk||""),t.base&&(t.base=Object.keys(t.base).length?[t.base]:[]),t.meta&&(t.meta=t.meta.filter((function(n,t,e){return!n[i]||t===K(e,(function(t){return t[i]===n[i]}))})),t.meta.forEach((function(t){return nn(n,t)}))),U(n,t,e)}(t,rn(t,n),P,n),r=vn(n._vueMeta.l,t,e);r&&a(e.changed)&&(e.changed(e,r.D,r.K),r={addedTags:r.D,removedTags:r.K});var i=yn();if(i){for(var o in i)vn(o,t,i[o]),delete i[o];hn(!0)}return{vm:n,metaInfo:e,tags:r}}function bn(n){n=n||{};var t=this.$root;return{getOptions:function(){return function(n){var t={};for(var e in n)t[e]=n[e];return t}(n)},setOptions:function(e){e&&e.I&&(n.I=!!e.I,$(t));if(e&&"debounceWait"in e){var r=parseInt(e.t);isNaN(r)||(n.t=r)}e&&"waitOnDestroyed"in e&&(n.O=!!e.O)},refresh:function(){return pn(t,n)},inject:function(){return s("inject")},pause:function(){return R(t)},resume:function(){return W(t)},addApp:function(e){return mn(t,e,n)}}}function gn(n,t){n.__vuemeta_installed||(n.__vuemeta_installed=!0,t=function(n){return{A:(n=o(n)?n:{}).keyName||l,v:n.attribute||v,g:n.ssrAttribute||m,m:n.tagIDKeyName||y,M:n.contentKeyName||h,k:n.metaTemplateKeyName||p,t:i(n.debounceWait)?g:n.debounceWait,O:i(n.waitOnDestroyed)?b:n.waitOnDestroyed,j:n.ssrAppId||w,I:!!n.refreshOnceOnNavigation}}(t),n.prototype.$meta=function(){return bn.call(this,t)},n.mixin(H(n,t)))}return i(window)||i(window.Vue)||gn(window.Vue),{version:"2.3.4",install:gn,generate:function(n,t){return s("generate")},hasMetaInfo:J}})); diff --git a/package.json b/package.json index 99205b7..92802a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-meta", - "version": "2.3.3", + "version": "2.3.4", "description": "Manage HTML metadata in Vue.js components with ssr support", "keywords": [ "attribute",