From 0ce55bef55a1dfe001d5e85f9adeb0da097e7407 Mon Sep 17 00:00:00 2001 From: Erik Vavro Date: Wed, 27 Jul 2022 08:57:40 -0400 Subject: [PATCH] build: Integrated babel into build to make bundle compatible with ES5 refers to #773 --- babel.config.js | 16 + build/rollup.config.js | 18 +- dist/vue-meta.cjs.js | 2301 ++++++++++++++++++------------ dist/vue-meta.cjs.prod.js | 2264 +++++++++++++++++------------ dist/vue-meta.d.ts | 2 +- dist/vue-meta.esm-browser.js | 2290 +++++++++++++++++------------ dist/vue-meta.esm-browser.min.js | 2 +- dist/vue-meta.esm-bundler.js | 2290 +++++++++++++++++------------ dist/vue-meta.global.js | 2297 +++++++++++++++++------------ dist/vue-meta.global.min.js | 2 +- package.json | 4 + 11 files changed, 6974 insertions(+), 4512 deletions(-) create mode 100644 babel.config.js diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..2d747fc0 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,16 @@ +module.exports = { + plugins: [ + ['@babel/plugin-transform-runtime', { regenerator: true }], // Needed for IE9 build target + ], + presets: [ + [ + '@babel/preset-env', + { + targets: { + node: 'current', + ie: 9, + }, + }, + ], + ], +} diff --git a/build/rollup.config.js b/build/rollup.config.js index fc4a414b..30a3e944 100644 --- a/build/rollup.config.js +++ b/build/rollup.config.js @@ -1,6 +1,7 @@ import path from 'path' import alias from '@rollup/plugin-alias' -// import babel from '@rollup/plugin-babel' +import babel from '@rollup/plugin-babel' +import { DEFAULT_EXTENSIONS } from '@babel/core' import commonjs from '@rollup/plugin-commonjs' import nodeResolve from '@rollup/plugin-node-resolve' import replace from '@rollup/plugin-replace' @@ -62,11 +63,10 @@ function rollupConfig ({ vue: 'Vue' } }, - external, + external: [...external, /@babel\/runtime/], plugins: [ replace(replaceConfig), nodeResolve(), - commonjs(), ts({ check: !didTS, tsconfig: r('../tsconfig.json'), @@ -79,7 +79,17 @@ function rollupConfig ({ }, exclude: ['node_modules', '__tests__', 'test-dts'] } - }) + }), + babel({ + babelHelpers: 'runtime', + exclude: 'node_modules/**', + extensions: [ + ...DEFAULT_EXTENSIONS, + '.ts', + '.tsx' + ] + }), + commonjs() ].concat(plugins) }) diff --git a/dist/vue-meta.cjs.js b/dist/vue-meta.cjs.js index b756b570..c76e261e 100644 --- a/dist/vue-meta.cjs.js +++ b/dist/vue-meta.cjs.js @@ -10,42 +10,71 @@ Object.defineProperty(exports, '__esModule', { value: true }); +var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator'); +var _classCallCheck = require('@babel/runtime/helpers/classCallCheck'); +var _createClass = require('@babel/runtime/helpers/createClass'); +var _defineProperty = require('@babel/runtime/helpers/defineProperty'); +var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray'); +var _regeneratorRuntime = require('@babel/runtime/regenerator'); var vue = require('vue'); +var _typeof = require('@babel/runtime/helpers/typeof'); +var _slicedToArray = require('@babel/runtime/helpers/slicedToArray'); -const resolveOption = (predicament, initialValue) => (options, contexts) => { - let resolvedIndex = -1; - contexts.reduce((acc, context, index) => { - const retval = predicament(acc, context); - if (retval !== acc) { - resolvedIndex = index; - return retval; - } - return acc; - }, initialValue); - if (resolvedIndex > -1) { - return options[resolvedIndex]; - } +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } + +var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator); +var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck); +var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass); +var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); +var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); +var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime); +var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof); +var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); + +var resolveOption = function resolveOption(predicament, initialValue) { + return function (options, contexts) { + var resolvedIndex = -1; + contexts.reduce(function (acc, context, index) { + var retval = predicament(acc, context); + + if (retval !== acc) { + resolvedIndex = index; + return retval; + } + + return acc; + }, initialValue); + + if (resolvedIndex > -1) { + return options[resolvedIndex]; + } + }; +}; + +var setup = function setup(context) { + var depth = 0; + + if (context.vm) { + var vm = context.vm; + + do { + if (vm.parent) { + depth++; + vm = vm.parent; + } + } while (vm && vm.parent && vm !== vm.root); + } + + context.depth = depth; }; +var resolve = resolveOption(function (currentValue, context) { + var depth = context.depth; + + if (!currentValue || depth > currentValue) { + return depth; + } -const setup = (context) => { - let depth = 0; - if (context.vm) { - let { vm } = context; - do { - if (vm.parent) { - depth++; - vm = vm.parent; - } - } while (vm && vm.parent && vm !== vm.root); - } - context.depth = depth; -}; -const resolve = resolveOption((currentValue, context) => { - const { depth } = context; - if (!currentValue || depth > currentValue) { - return depth; - } - return currentValue; + return currentValue; }); var defaultResolver = /*#__PURE__*/Object.freeze({ @@ -54,105 +83,98 @@ var defaultResolver = /*#__PURE__*/Object.freeze({ resolve: resolve }); -const defaultConfig = { - body: { - tag: 'script', - to: 'body' - }, - base: { - valueAttribute: 'href' - }, - charset: { - tag: 'meta', - nameless: true, - valueAttribute: 'charset' - }, - description: { - tag: 'meta' - }, - og: { - group: true, - namespacedAttribute: true, - tag: 'meta', - keyAttribute: 'property' - }, - twitter: { - group: true, - namespacedAttribute: true, - tag: 'meta' - }, - htmlAttrs: { - attributesFor: 'html' - }, - headAttrs: { - attributesFor: 'head' - }, - bodyAttrs: { - attributesFor: 'body' - } +var defaultConfig = { + body: { + tag: 'script', + to: 'body' + }, + base: { + valueAttribute: 'href' + }, + charset: { + tag: 'meta', + nameless: true, + valueAttribute: 'charset' + }, + description: { + tag: 'meta' + }, + og: { + group: true, + namespacedAttribute: true, + tag: 'meta', + keyAttribute: 'property' + }, + twitter: { + group: true, + namespacedAttribute: true, + tag: 'meta' + }, + htmlAttrs: { + attributesFor: 'html' + }, + headAttrs: { + attributesFor: 'head' + }, + bodyAttrs: { + attributesFor: 'body' + } }; /* * This is a fixed config for real HTML tags - */ -const tags = { - title: { - attributes: false - }, - base: { - contentAsAttribute: true, - attributes: ['href', 'target'] - }, - meta: { - contentAsAttribute: true, - keyAttribute: 'name', - attributes: ['content', 'name', 'http-equiv', 'charset'] - }, - link: { - contentAsAttribute: true, - attributes: [ - 'href', - 'crossorigin', - 'rel', - 'media', - 'integrity', - 'hreflang', - 'type', - 'referrerpolicy', - 'sizes', - 'imagesrcset', - 'imagesizes', - 'as', - 'color' - ] - }, - style: { - attributes: ['media'] - }, - script: { - attributes: [ - 'src', - 'type', - 'nomodule', - 'async', - 'defer', - 'crossorigin', - 'integrity', - 'referrerpolicy' - ] - }, - noscript: { - attributes: false - } + */ +var tags = { + title: { + attributes: false + }, + base: { + contentAsAttribute: true, + attributes: ['href', 'target'] + }, + meta: { + contentAsAttribute: true, + keyAttribute: 'name', + attributes: ['content', 'name', 'http-equiv', 'charset'] + }, + link: { + contentAsAttribute: true, + attributes: ['href', 'crossorigin', 'rel', 'media', 'integrity', 'hreflang', 'type', 'referrerpolicy', 'sizes', 'imagesrcset', 'imagesizes', 'as', 'color'] + }, + style: { + attributes: ['media'] + }, + script: { + attributes: ['src', 'type', 'nomodule', 'async', 'defer', 'crossorigin', 'integrity', 'referrerpolicy'] + }, + noscript: { + attributes: false + } }; -function getTagConfigItem(tagOrName, key) { - for (const name of tagOrName) { - const tag = tags[name]; - if (name && tag) { - return tag[key]; - } - } +function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(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$5(o, minLen); } + +function _arrayLikeToArray$5(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 getTagConfigItem(tagOrName, key) { + var _iterator = _createForOfIteratorHelper$5(tagOrName), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var name = _step.value; + var tag = tags[name]; + + if (name && tag) { + return tag[key]; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } } /** @@ -162,6 +184,7 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ + Object.freeze({}) ; Object.freeze([]) ; @@ -173,805 +196,1275 @@ const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const isPlainObject = (val) => toTypeString(val) === '[object Object]'; -// https://github.com/microsoft/TypeScript/issues/1863 -const IS_PROXY = Symbol('kIsProxy'); -const PROXY_SOURCES = Symbol('kProxySources'); -const PROXY_TARGET = Symbol('kProxyTarget'); -const RESOLVE_CONTEXT = Symbol('kResolveContext'); - -// See: https://github.com/vuejs/vue-next/blob/08b4e8815da4e8911058ccbab986bea6365c3352/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts -function clone(v) { - if (isArray(v)) { - return v.map(clone); - } - if (isObject(v)) { - const res = {}; - for (const key in v) { - // never clone the context - if (key === 'context') { - res[key] = v[key]; - } - else { - res[key] = clone(v[key]); - } - } - return res; - } - return v; +// https://github.com/microsoft/TypeScript/issues/1863 +var IS_PROXY = Symbol('kIsProxy'); +var PROXY_SOURCES = Symbol('kProxySources'); +var PROXY_TARGET = Symbol('kProxyTarget'); +var RESOLVE_CONTEXT = Symbol('kResolveContext'); + +function clone(v) { + if (isArray(v)) { + return v.map(clone); + } + + if (isObject(v)) { + var res = {}; + + for (var key in v) { + // never clone the context + if (key === 'context') { + res[key] = v[key]; + } else { + res[key] = clone(v[key]); + } + } + + return res; + } + + return v; } -const pluck = (collection, key, callback) => { - const plucked = []; - for (const row of collection) { - if (row && key in row) { - plucked.push(row[key]); - if (callback) { - callback(row); - } - } - } - return plucked; +function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(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$4(o, minLen); } + +function _arrayLikeToArray$4(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; } + +var pluck = function pluck(collection, key, callback) { + var plucked = []; + + var _iterator = _createForOfIteratorHelper$4(collection), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var row = _step.value; + + if (row && key in row) { + plucked.push(row[key]); + + if (callback) { + callback(row); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return plucked; }; -const allKeys = (source, ...sources) => { - const keys = source ? Object.keys(source) : []; - if (sources) { - for (const source of sources) { - if (!source || !isObject(source)) { - continue; - } - for (const key in source) { - if (!keys.includes(key)) { - keys.push(key); - } - } - } - } - // TODO: add check for consistent types for each key (dev only) - return keys; -}; -const recompute = (context, path = [], target, sources) => { - const setTargetAndSources = !target && !sources; - if (setTargetAndSources) { - ({ active: target, sources } = context); - if (path.length) { - for (let i = 0; i < path.length; i++) { - const seg = path[i]; - if (!target || !target[seg]) { - { - // eslint-disable-next-line no-console - console.error(`recompute: segment ${seg} not found on target`, path, target); - } - return; - } - target = target[seg]; - sources = sources.map(source => source[seg]).filter(Boolean); - } - } - } - if (!target || !sources) { - return; - } - const keys = allKeys(...sources); - // Clean up properties that dont exists anymore - const targetKeys = Object.keys(target); - for (const key of targetKeys) { - if (!keys.includes(key)) { - delete target[key]; - } - } - for (const key of keys) { - // This assumes consistent types usages for keys across sources - // @ts-ignore - let isObject = false; - for (let i = 0; i < sources.length; i++) { - const source = sources[i]; - if (source && key in source && source[key] !== undefined) { - isObject = isPlainObject(source[key]); - break; - } - } - if (isObject) { - if (!target[key]) { - target[key] = {}; - } - const keySources = []; - for (const source of sources) { - if (key in source) { - // @ts-ignore - keySources.push(source[key]); - } - } - recompute(context, [...path, key], target[key], keySources); - continue; - } - // Ensure the target is an array if source is an array and target is empty - // @ts-ignore - if (!target[key] && isArray(sources[0][key])) { - target[key] = []; - } - const keyContexts = []; - const keySources = pluck(sources, key, source => keyContexts.push(source[RESOLVE_CONTEXT])); - let resolved = context.resolve(keySources, keyContexts, target[key], key, path); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - target[key] = resolved; - } +var debugFn = function debugFn(logFn) { + var setChildFns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fn = function fn() { + try { + throw new Error('DEBUG'); + } catch (err) { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logFn.apply(void 0, args.concat(['\n', err])); + } + }; + + if (setChildFns) { + fn.warn = debugFn(console.warn); // eslint-disable-line no-console + + fn.error = debugFn(console.error); // eslint-disable-line no-console + } + + return fn; }; +debugFn(console.log, true); // eslint-disable-line no-console + +function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(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$3(o, minLen); } + +function _arrayLikeToArray$3(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; } +var allKeys = function allKeys(source) { + var keys = source ? Object.keys(source) : []; + + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (sources) { + var _iterator = _createForOfIteratorHelper$3(sources), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _source = _step.value; + + if (!_source || !isObject(_source)) { + continue; + } + + for (var key in _source) { + if (!keys.includes(key)) { + keys.push(key); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } // TODO: add check for consistent types for each key (dev only) -const createProxy = (context, target, resolveContext, pathSegments = []) => { - const handler = createHandler(context, resolveContext, pathSegments); - const proxy = vue.markRaw(new Proxy(target, handler)); - if (!pathSegments.length && context.sources) { - context.sources.push(proxy); - } - return proxy; -}; -const createHandler = (context, resolveContext, pathSegments = []) => ({ - get: (target, key, receiver) => { - if (key === IS_PROXY) { - return true; - } - if (key === PROXY_SOURCES) { - return context.sources; - } - if (key === PROXY_TARGET) { - return target; - } - if (key === RESOLVE_CONTEXT) { - return resolveContext; - } - let value = Reflect.get(target, key, receiver); - if (!isObject(value)) { - return value; - } - // Also return a merge proxy for nested objects - if (!value[IS_PROXY]) { - const keyPath = [...pathSegments, key]; - value = createProxy(context, value, resolveContext, keyPath); - Reflect.set(target, key, value); - } - return value; - }, - set: (target, key, value) => { - const success = Reflect.set(target, key, value); - // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) - if (success) { - const isArrayItem = isArray(target); - let hasArrayParent = false; - let { sources: proxies, active } = context; - let activeSegmentKey; - let index = 0; - for (const segment of pathSegments) { - proxies = pluck(proxies, segment); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - if (isArray(active)) { - hasArrayParent = true; - } - active = active[segment]; - index++; - } - if (hasArrayParent) { - // TODO: fix that we dont have to recompute the full merged object - // we should only have to recompute the branch that has changed - // but there is an issue here with supporting both arrays of strings - // as collections (parent vs parent of parent we need to trigger the - // update from) - recompute(context); - return success; - } - else if (isPlainObject(value)) { - // if an object was assigned to this key make sure to recompute all - // of its individual properies - recompute(context, pathSegments); - return success; - } - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - // Ensure to clone if value is an object, cause sources is an array of - // the sourceProxies and not the sources so we could trigger an endless loop when - // updating a prop on an obj as the prop on the active object refers to - // a prop on a proxy - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) - return success; - }, - deleteProperty: (target, key) => { - const success = Reflect.deleteProperty(target, key); - // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) - if (success) { - const isArrayItem = isArray(target); - let activeSegmentKey; - let proxies = context.sources; - let active = context.active; - let index = 0; - for (const segment of pathSegments) { - // @ts-ignore - proxies = proxies.map(proxy => proxy && proxy[segment]); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - active = active[segment]; - index++; - } - // Check if the key still exists in one of the sourceProxies, - // if so resolve the new value, if not remove the key - if (proxies.some(proxy => proxy && (key in proxy))) { - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', resolved) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - else { - delete active[key]; - } - } - return success; - } -}); -const createMergedObject = (resolve, active) => { - const sources = []; - const context = { - active, - resolve, - sources - }; - const compute = () => recompute(context); - return { - context, - compute, - addSource: (source, resolveContext, recompute = false) => { - const proxy = createProxy(context, source, resolveContext || {}); - if (recompute) { - compute(); - } - return proxy; - }, - delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); - if (index > -1) { - sources.splice(index, 1); - if (recompute) { - compute(); - } - return true; - } - return false; - } - }; + return keys; }; +var recompute = function recompute(context) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var target = arguments.length > 2 ? arguments[2] : undefined; + var sources = arguments.length > 3 ? arguments[3] : undefined; + var setTargetAndSources = !target && !sources; + + if (setTargetAndSources) { + target = context.active; + sources = context.sources; + + if (path.length) { + var _loop = function _loop(i) { + var seg = path[i]; + + if (!target || !target[seg]) { + { + // eslint-disable-next-line no-console + console.error("recompute: segment ".concat(seg, " not found on target"), path, target); + } + + return { + v: void 0 + }; + } + + target = target[seg]; + sources = sources.map(function (source) { + return source[seg]; + }).filter(Boolean); + }; + + for (var i = 0; i < path.length; i++) { + var _ret = _loop(i); + + if (_typeof__default(_ret) === "object") return _ret.v; + } + } + } + + if (!target || !sources) { + return; + } + + var keys = allKeys.apply(void 0, _toConsumableArray__default(sources)); // Clean up properties that dont exists anymore + + var targetKeys = Object.keys(target); + + for (var _i = 0, _targetKeys = targetKeys; _i < _targetKeys.length; _i++) { + var key = _targetKeys[_i]; + + if (!keys.includes(key)) { + delete target[key]; + } + } + + var _iterator2 = _createForOfIteratorHelper$3(keys), + _step2; + + try { + var _loop2 = function _loop2() { + var key = _step2.value; + // This assumes consistent types usages for keys across sources + // @ts-ignore + var isObject = false; + + for (var _i2 = 0; _i2 < sources.length; _i2++) { + var source = sources[_i2]; + + if (source && key in source && source[key] !== undefined) { + isObject = isPlainObject(source[key]); + break; + } + } + + if (isObject) { + if (!target[key]) { + target[key] = {}; + } + + var _keySources = []; + + var _iterator3 = _createForOfIteratorHelper$3(sources), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _source2 = _step3.value; + + if (key in _source2) { + // @ts-ignore + _keySources.push(_source2[key]); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + recompute(context, [].concat(_toConsumableArray__default(path), [key]), target[key], _keySources); + return "continue"; + } // Ensure the target is an array if source is an array and target is empty + // @ts-ignore + + + if (!target[key] && isArray(sources[0][key])) { + target[key] = []; + } + + var keyContexts = []; + var keySources = pluck(sources, key, function (source) { + return keyContexts.push(source[RESOLVE_CONTEXT]); + }); + var resolved = context.resolve(keySources, keyContexts, target[key], key, path); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } -const cachedElements = {}; -function renderMeta(context, key, data, config) { - // console.info('renderMeta', key, data, config) - if ('attributesFor' in config) { - return renderAttributes(context, key, data, config); - } - if ('group' in config) { - return renderGroup(context, key, data, config); - } - return renderTag(context, key, data, config); -} -function renderGroup(context, key, data, config) { - // console.info('renderGroup', key, data, config) - if (isArray(data)) { - { - // eslint-disable-next-line no-console - console.warn('Specifying an array for group properties isnt supported'); - } - // config.attributes = getConfigKey([key, config.tag], 'attributes', config) - return []; - } - return Object.keys(data) - .map((childKey) => { - const groupConfig = { - group: key, - data - }; - if (config.namespaced) { - groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; - } - else if (config.namespacedAttribute) { - const namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; - groupConfig.fullName = `${namespace}:${childKey}`; - groupConfig.slotName = `${namespace}(${childKey})`; - } - return renderTag(context, key, data[childKey], config, groupConfig); - }) - .filter(Boolean) - .flat(); -} -function renderTag(context, key, data, config = {}, groupConfig) { - // console.info('renderTag', key, data, config, groupConfig) - const contentAttributes = ['content', 'json', 'rawContent']; - const getTagConfig = (key) => getTagConfigItem([tag, config.tag], key); - if (isArray(data)) { - return data - .map((child) => { - return renderTag(context, key, child, config, groupConfig); - }) - .filter(Boolean) - .flat(); - } - const { tag = config.tag || key } = data; - let content = ''; - let hasChilds = false; - let isRaw = false; - if (isString(data)) { - content = data; - } - else if (data.children && isArray(data.children)) { - hasChilds = true; - content = data.children.map((child) => { - const data = renderTag(context, key, child, config, groupConfig); - if (isArray(data)) { - return data.map(({ vnode }) => vnode); - } - return data && data.vnode; - }); - } - else { - let i = 0; - for (const contentAttribute of contentAttributes) { - if (!content && data[contentAttribute]) { - if (i === 1) { - content = JSON.stringify(data[contentAttribute]); - } - else { - content = data[contentAttribute]; - } - isRaw = i > 1; - break; - } - i++; - } - } - const fullName = (groupConfig && groupConfig.fullName) || key; - const slotName = (groupConfig && groupConfig.slotName) || key; - let { attrs: attributes } = data; - if (!attributes && typeof data === 'object') { - attributes = { ...data }; - delete attributes.tag; - delete attributes.children; - delete attributes.to; - // cleanup all content attributes - for (const attr of contentAttributes) { - delete attributes[attr]; - } - } - else if (!attributes) { - attributes = {}; - } - if (hasChilds) { - content = getSlotContent(context, slotName, content, data); - } - else { - const contentAsAttribute = !!getTagConfig('contentAsAttribute'); - let { valueAttribute } = config; - if (!valueAttribute && contentAsAttribute) { - const [tagAttribute] = getTagConfig('attributes'); - valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; - } - if (!valueAttribute) { - content = getSlotContent(context, slotName, content, data); - } - else { - const { nameless } = config; - if (!nameless) { - const keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); - if (keyAttribute) { - attributes[keyAttribute] = fullName; - } - } - attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); - content = ''; - } - } - const finalTag = groupConfig && groupConfig.tagNamespace - ? `${groupConfig.tagNamespace}:${tag}` - : tag; - if (finalTag === 'title' && !context.isSSR) { - document.title = content; - return; - } - // console.info('FINAL TAG', finalTag) - // console.log(' ATTRIBUTES', attributes) - // console.log(' CONTENT', content) - // console.log(data, attributes, config) - if (isRaw && content) { - attributes.innerHTML = content; - } - // Ignore empty string content - const vnode = vue.h(finalTag, attributes, content || undefined); - return { - to: data.to, - vnode - }; -} -function renderAttributes(context, key, data, config) { - // console.info('renderAttributes', key, data, config) - const { attributesFor } = config; - if (!attributesFor || !data) { - return; - } - if (context.isSSR) { - // render attributes in a placeholder vnode so Vue - // will render the string for us - return { - to: '', - vnode: vue.h(`ssr-${attributesFor}`, data) - }; - } - if (!cachedElements[attributesFor]) { - const [el, el2] = Array.from(document.querySelectorAll(attributesFor)); - if (!el) { - // eslint-disable-next-line no-console - console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); - return; - } - if (el2) { - // eslint-disable-next-line no-console - console.warn('Found multiple elements for selector', attributesFor); - } - cachedElements[attributesFor] = { - el, - attrs: [] - }; - } - const { el, attrs } = cachedElements[attributesFor]; - for (const attr in data) { - let content = getSlotContent(context, `${key}(${attr})`, data[attr], data); - if (isArray(content)) { - content = content.join(','); - } - el.setAttribute(attr, content || ''); - if (!attrs.includes(attr)) { - attrs.push(attr); - } - } - const attrsToRemove = attrs.filter(attr => !data[attr]); - for (const attr of attrsToRemove) { - el.removeAttribute(attr); - } -} -function getSlotContent({ metainfo, slots }, slotName, content, groupConfig) { - const slot = slots && slots[slotName]; - if (!slot || !isFunction(slot)) { - return content; - } - const slotScopeProps = { - content, - metainfo - }; - if (groupConfig && groupConfig.group) { - const { group, data } = groupConfig; - slotScopeProps[group] = data; - } - const slotContent = slot(slotScopeProps); - if (slotContent && slotContent.length) { - const { children } = slotContent[0]; - return children ? children.toString() : ''; - } - return content; + target[key] = resolved; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret2 = _loop2(); + + if (_ret2 === "continue") continue; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } +}; + +function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(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$2(o, minLen); } + +function _arrayLikeToArray$2(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; } +var createProxy = function createProxy(context, target, resolveContext) { + var pathSegments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + var handler = createHandler(context, resolveContext, pathSegments); + var proxy = vue.markRaw(new Proxy(target, handler)); + + if (!pathSegments.length && context.sources) { + context.sources.push(proxy); + } + + return proxy; +}; +var createHandler = function createHandler(context, resolveContext) { + var pathSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + return { + get: function get(target, key, receiver) { + if (key === IS_PROXY) { + return true; + } + + if (key === PROXY_SOURCES) { + return context.sources; + } + + if (key === PROXY_TARGET) { + return target; + } + + if (key === RESOLVE_CONTEXT) { + return resolveContext; + } + + var value = Reflect.get(target, key, receiver); + + if (!isObject(value)) { + return value; + } // Also return a merge proxy for nested objects + + + if (!value[IS_PROXY]) { + var keyPath = [].concat(_toConsumableArray__default(pathSegments), [key]); + value = createProxy(context, value, resolveContext, keyPath); + Reflect.set(target, key, value); + } + + return value; + }, + set: function set(target, key, value) { + var success = Reflect.set(target, key, value); // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) + + if (success) { + var isArrayItem = isArray(target); + var hasArrayParent = false; + var proxies = context.sources, + active = context.active; + var activeSegmentKey; + var index = 0; + + var _iterator = _createForOfIteratorHelper$2(pathSegments), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var segment = _step.value; + proxies = pluck(proxies, segment); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + break; + } + + if (isArray(active)) { + hasArrayParent = true; + } + + active = active[segment]; + index++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + if (hasArrayParent) { + // TODO: fix that we dont have to recompute the full merged object + // we should only have to recompute the branch that has changed + // but there is an issue here with supporting both arrays of strings + // as collections (parent vs parent of parent we need to trigger the + // update from) + recompute(context); + return success; + } else if (isPlainObject(value)) { + // if an object was assigned to this key make sure to recompute all + // of its individual properies + recompute(context, pathSegments); + return success; + } + + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); // Ensure to clone if value is an object, cause sources is an array of + // the sourceProxies and not the sources so we could trigger an endless loop when + // updating a prop on an obj as the prop on the active object refers to + // a prop on a proxy + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) + + + return success; + }, + deleteProperty: function deleteProperty(target, key) { + var success = Reflect.deleteProperty(target, key); // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) + + if (success) { + var isArrayItem = isArray(target); + var activeSegmentKey; + var proxies = context.sources; + var active = context.active; + var index = 0; + + var _iterator2 = _createForOfIteratorHelper$2(pathSegments), + _step2; + + try { + var _loop = function _loop() { + var segment = _step2.value; + // @ts-ignore + proxies = proxies.map(function (proxy) { + return proxy && proxy[segment]; + }); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + return "break"; + } + + active = active[segment]; + index++; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret = _loop(); + + if (_ret === "break") break; + } // Check if the key still exists in one of the sourceProxies, + // if so resolve the new value, if not remove the key + + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + if (proxies.some(function (proxy) { + return proxy && key in proxy; + })) { + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', resolved) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } else { + delete active[key]; + } + } + + return success; + } + }; +}; + +var createMergedObject = function createMergedObject(resolve, active) { + var sources = []; + var context = { + active: active, + resolve: resolve, + sources: sources + }; + + var compute = function compute() { + return recompute(context); + }; + + return { + context: context, + compute: compute, + addSource: function addSource(source, resolveContext) { + var recompute = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var proxy = createProxy(context, source, resolveContext || {}); + + if (recompute) { + compute(); + } + + return proxy; + }, + delSource: function delSource(sourceOrProxy) { + var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var index = sources.findIndex(function (source) { + return source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy; + }); + + if (index > -1) { + sources.splice(index, 1); + + if (recompute) { + compute(); + } + + return true; + } + + return false; + } + }; +}; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(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$1(o, minLen); } + +function _arrayLikeToArray$1(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; } +var cachedElements = {}; +function renderMeta(context, key, data, config) { + // console.info('renderMeta', key, data, config) + if ('attributesFor' in config) { + return renderAttributes(context, key, data, config); + } + + if ('group' in config) { + return renderGroup(context, key, data, config); + } + + return renderTag(context, key, data, config); } +function renderGroup(context, key, data, config) { + // console.info('renderGroup', key, data, config) + if (isArray(data)) { + { + // eslint-disable-next-line no-console + console.warn('Specifying an array for group properties isnt supported'); + } // config.attributes = getConfigKey([key, config.tag], 'attributes', config) + -const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; -const PolySymbol = (name) => -// vm = vue meta -hasSymbol - ? Symbol('[vue-meta]: ' + name ) - : ('[vue-meta]: ' ) + name; -const metaActiveKey = /*#__PURE__*/ PolySymbol('meta_active' ); + return []; + } + + return Object.keys(data).map(function (childKey) { + var groupConfig = { + group: key, + data: data + }; + + if (config.namespaced) { + groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; + } else if (config.namespacedAttribute) { + var namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; + groupConfig.fullName = "".concat(namespace, ":").concat(childKey); + groupConfig.slotName = "".concat(namespace, "(").concat(childKey, ")"); + } + + return renderTag(context, key, data[childKey], config, groupConfig); + }).filter(Boolean).flat(); +} +function renderTag(context, key, data) { + var config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var groupConfig = arguments.length > 4 ? arguments[4] : undefined; + // console.info('renderTag', key, data, config, groupConfig) + var contentAttributes = ['content', 'json', 'rawContent']; + + var getTagConfig = function getTagConfig(key) { + return getTagConfigItem([tag, config.tag], key); + }; + + if (isArray(data)) { + return data.map(function (child) { + return renderTag(context, key, child, config, groupConfig); + }).filter(Boolean).flat(); + } + + var _data$tag = data.tag, + tag = _data$tag === void 0 ? config.tag || key : _data$tag; + var content = ''; + var hasChilds = false; + var isRaw = false; + + if (isString(data)) { + content = data; + } else if (data.children && isArray(data.children)) { + hasChilds = true; + content = data.children.map(function (child) { + var data = renderTag(context, key, child, config, groupConfig); + + if (isArray(data)) { + return data.map(function (_ref) { + var vnode = _ref.vnode; + return vnode; + }); + } + + return data && data.vnode; + }); + } else { + var i = 0; + + var _iterator = _createForOfIteratorHelper$1(contentAttributes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var contentAttribute = _step.value; + + if (!content && data[contentAttribute]) { + if (i === 1) { + content = JSON.stringify(data[contentAttribute]); + } else { + content = data[contentAttribute]; + } + + isRaw = i > 1; + break; + } + + i++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + var fullName = groupConfig && groupConfig.fullName || key; + var slotName = groupConfig && groupConfig.slotName || key; + var attributes = data.attrs; + + if (!attributes && _typeof__default(data) === 'object') { + attributes = _objectSpread({}, data); + delete attributes.tag; + delete attributes.children; + delete attributes.to; // cleanup all content attributes + + var _iterator2 = _createForOfIteratorHelper$1(contentAttributes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var attr = _step2.value; + delete attributes[attr]; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } else if (!attributes) { + attributes = {}; + } + + if (hasChilds) { + content = getSlotContent(context, slotName, content, data); + } else { + var contentAsAttribute = !!getTagConfig('contentAsAttribute'); + var valueAttribute = config.valueAttribute; + + if (!valueAttribute && contentAsAttribute) { + var _getTagConfig = getTagConfig('attributes'), + _getTagConfig2 = _slicedToArray__default(_getTagConfig, 1), + tagAttribute = _getTagConfig2[0]; + + valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; + } + + if (!valueAttribute) { + content = getSlotContent(context, slotName, content, data); + } else { + var nameless = config.nameless; + + if (!nameless) { + var keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); + + if (keyAttribute) { + attributes[keyAttribute] = fullName; + } + } + + attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); + content = ''; + } + } + + var finalTag = groupConfig && groupConfig.tagNamespace ? "".concat(groupConfig.tagNamespace, ":").concat(tag) : tag; + + if (finalTag === 'title' && !context.isSSR) { + document.title = content; + return; + } // console.info('FINAL TAG', finalTag) + // console.log(' ATTRIBUTES', attributes) + // console.log(' CONTENT', content) + // console.log(data, attributes, config) + + + if (isRaw && content) { + attributes.innerHTML = content; + } // Ignore empty string content + + + var vnode = vue.h(finalTag, attributes, content || undefined); + return { + to: data.to, + vnode: vnode + }; +} +function renderAttributes(context, key, data, config) { + // console.info('renderAttributes', key, data, config) + var attributesFor = config.attributesFor; + + if (!attributesFor || !data) { + return; + } + + if (context.isSSR) { + // render attributes in a placeholder vnode so Vue + // will render the string for us + return { + to: '', + vnode: vue.h("ssr-".concat(attributesFor), data) + }; + } + + if (!cachedElements[attributesFor]) { + var _Array$from = Array.from(document.querySelectorAll(attributesFor)), + _Array$from2 = _slicedToArray__default(_Array$from, 2), + _el = _Array$from2[0], + el2 = _Array$from2[1]; + + if (!_el) { + // eslint-disable-next-line no-console + console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); + return; + } + + if (el2) { + // eslint-disable-next-line no-console + console.warn('Found multiple elements for selector', attributesFor); + } + + cachedElements[attributesFor] = { + el: _el, + attrs: [] + }; + } + + var _cachedElements$attri = cachedElements[attributesFor], + el = _cachedElements$attri.el, + attrs = _cachedElements$attri.attrs; + + for (var attr in data) { + var content = getSlotContent(context, "".concat(key, "(").concat(attr, ")"), data[attr], data); + + if (isArray(content)) { + content = content.join(','); + } + + el.setAttribute(attr, content || ''); + + if (!attrs.includes(attr)) { + attrs.push(attr); + } + } + + var attrsToRemove = attrs.filter(function (attr) { + return !data[attr]; + }); + + var _iterator3 = _createForOfIteratorHelper$1(attrsToRemove), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _attr = _step3.value; + el.removeAttribute(_attr); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } +} +function getSlotContent(_ref2, slotName, content, groupConfig) { + var metainfo = _ref2.metainfo, + slots = _ref2.slots; + var slot = slots && slots[slotName]; + + if (!slot || !isFunction(slot)) { + return content; + } + + var slotScopeProps = { + content: content, + metainfo: metainfo + }; + + if (groupConfig && groupConfig.group) { + var group = groupConfig.group, + data = groupConfig.data; + slotScopeProps[group] = data; + } + + var slotContent = slot(slotScopeProps); + + if (slotContent && slotContent.length) { + var children = slotContent[0].children; + return children ? children.toString() : ''; + } + + return content; +} + +var hasSymbol = typeof Symbol === 'function' && _typeof__default(Symbol.toStringTag) === 'symbol'; +var PolySymbol = function PolySymbol(name) { + return (// vm = vue meta + hasSymbol ? Symbol('[vue-meta]: ' + name ) : ('[vue-meta]: ' ) + name + ); +}; +var metaActiveKey = /*#__PURE__*/PolySymbol('meta_active' ); /** * Apply the differences between newSource & oldSource to target - */ -function applyDifference(target, newSource, oldSource) { - for (const key in newSource) { - if (!(key in oldSource)) { - target[key] = newSource[key]; - continue; - } - if (isObject(target[key])) { - applyDifference(target[key], newSource[key], oldSource[key]); - continue; - } - if (newSource[key] !== oldSource[key]) { - target[key] = newSource[key]; - } - } - for (const key in oldSource) { - if (!newSource || !(key in newSource)) { - delete target[key]; - } - } + */ + +function applyDifference(target, newSource, oldSource) { + for (var key in newSource) { + if (!(key in oldSource)) { + target[key] = newSource[key]; + continue; + } + + if (isObject(target[key])) { + applyDifference(target[key], newSource[key], oldSource[key]); + continue; + } + + if (newSource[key] !== oldSource[key]) { + target[key] = newSource[key]; + } + } + + for (var _key in oldSource) { + if (!newSource || !(_key in newSource)) { + delete target[_key]; + } + } } -function getCurrentManager(vm) { - if (!vm) { - vm = vue.getCurrentInstance() || undefined; - } - if (!vm) { - return undefined; - } - return vm.appContext.config.globalProperties.$metaManager; -} -function useMeta(source, manager) { - const vm = vue.getCurrentInstance() || undefined; - if (!manager && vm) { - manager = getCurrentManager(vm); - } - if (!manager) { - throw new Error('No manager or current instance'); - } - if (vue.isProxy(source)) { - vue.watch(source, (newSource, oldSource) => { - applyDifference(metaProxy.meta, newSource, oldSource); - }); - source = source.value; - } - const metaProxy = manager.addMeta(source, vm); - return metaProxy; -} -function useActiveMeta() { - return vue.inject(metaActiveKey); +function getCurrentManager(vm) { + if (!vm) { + vm = vue.getCurrentInstance() || undefined; + } + + if (!vm) { + return undefined; + } + + return vm.appContext.config.globalProperties.$metaManager; } +function useMeta(source, manager) { + var vm = vue.getCurrentInstance() || undefined; + + if (!manager && vm) { + manager = getCurrentManager(vm); + } + + if (!manager) { + throw new Error('No manager or current instance'); + } + + if (vue.isProxy(source)) { + vue.watch(source, function (newSource, oldSource) { + applyDifference(metaProxy.meta, newSource, oldSource); + }); + source = source.value; + } + + var metaProxy = manager.addMeta(source, vm); + return metaProxy; +} +function useActiveMeta() { + return vue.inject(metaActiveKey); +} + +var MetainfoImpl = vue.defineComponent({ + name: 'Metainfo', + inheritAttrs: false, + setup: function setup(_, _ref) { + var slots = _ref.slots; + return function () { + var manager = getCurrentManager(); + + if (!manager) { + return; + } + + return manager.render({ + slots: slots + }); + }; + } +}); +var Metainfo = MetainfoImpl; + +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +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; } +var ssrAttribute = 'data-vm-ssr'; +function addVnode(isSSR, teleports, to, vnodes) { + var _teleports$to; + + var nodes = isArray(vnodes) ? vnodes : [vnodes]; -const MetainfoImpl = vue.defineComponent({ - name: 'Metainfo', - inheritAttrs: false, - setup(_, { slots }) { - return () => { - const manager = getCurrentManager(); - if (!manager) { - return; - } - return manager.render({ slots }); - }; - } -}); -const Metainfo = MetainfoImpl; - -const ssrAttribute = 'data-vm-ssr'; -function addVnode(isSSR, teleports, to, vnodes) { - const nodes = (isArray(vnodes) ? vnodes : [vnodes]); - if (!isSSR) { - // Comments shouldnt have any use on the client as they are not reactive anyway - nodes.forEach((vnode, idx) => { - if (vnode.type === vue.Comment) { - nodes.splice(idx, 1); - } - }); - // only add ssrAttribute's for real meta tags - } - else if (!to.endsWith('Attrs')) { - nodes.forEach((vnode) => { - if (!vnode.props) { - vnode.props = {}; - } - vnode.props[ssrAttribute] = true; - }); - } - if (!teleports[to]) { - teleports[to] = []; - } - teleports[to].push(...nodes); -} -const createMetaManager = (isSSR = false, config, resolver) => MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); -class MetaManager { - isSSR = false; - config; - target; - resolver; - ssrCleanedUp = false; - constructor(isSSR, config, target, resolver) { - this.isSSR = isSSR; - this.config = config; - this.target = target; - if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { - this.resolver = resolver; - } - } - static create = (isSSR, config, resolver) => { - const resolve = (options, contexts, active, key, pathSegments) => { - if (isFunction(resolver)) { - return resolver(options, contexts, active, key, pathSegments); - } - return resolver.resolve(options, contexts, active, key, pathSegments); - }; - const active = vue.reactive({}); - const mergedObject = createMergedObject(resolve, active); - // TODO: validate resolver - const manager = new MetaManager(isSSR, config, mergedObject, resolver); - return manager; - }; - install(app) { - app.component('Metainfo', Metainfo); - app.config.globalProperties.$metaManager = this; - app.provide(metaActiveKey, this.target.context.active); - } - addMeta(metadata, vm) { - if (!vm) { - vm = vue.getCurrentInstance() || undefined; - } - const metaGuards = ({ - removed: [] - }); - const resolveContext = { vm }; - const { resolver } = this; - if (resolver && resolver.setup) { - resolver.setup(resolveContext); - } - // TODO: optimize initial compute (once) - const meta = this.target.addSource(metadata, resolveContext, true); - const onRemoved = (removeGuard) => metaGuards.removed.push(removeGuard); - const unmount = (ignoreGuards) => this.unmount(!!ignoreGuards, meta, metaGuards, vm); - if (vm) { - vue.onUnmounted(unmount); - } - return { - meta, - onRemoved, - unmount - }; - } - unmount(ignoreGuards, meta, metaGuards, vm) { - if (vm) { - const { $el } = vm.proxy; - // Wait for element to be removed from DOM - if ($el && $el.offsetParent) { - let observer = new MutationObserver((records) => { - for (const { removedNodes } of records) { - if (!removedNodes) { - continue; - } - removedNodes.forEach((el) => { - if (el === $el && observer) { - observer.disconnect(); - observer = undefined; - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - }); - } - }); - observer.observe($el.parentNode, { childList: true }); - return; - } - } - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - async reallyUnmount(ignoreGuards, meta, metaGuards) { - this.target.delSource(meta); - if (!ignoreGuards && metaGuards) { - await Promise.all(metaGuards.removed.map(removeGuard => removeGuard())); - } - } - render({ slots } = {}) { - const active = this.target.context.active; - // TODO: clean this method - const { isSSR } = this; - // cleanup ssr tags if not yet done - if (!isSSR && !this.ssrCleanedUp) { - this.ssrCleanedUp = true; - const cleanUpSSR = () => { - const ssrTags = document.querySelectorAll(`[${ssrAttribute}]`); - if (ssrTags && ssrTags.length) { - ssrTags.forEach(el => el.parentNode && el.parentNode.removeChild(el)); - } - }; - if (document.readyState === 'loading') { - // Listen for DOM loaded because tags in the body couldnt - // have loaded yet once the manager does it first render - // (preferable there should only be one meta render on hydration) - window.addEventListener('DOMContentLoaded', cleanUpSSR, { once: true }); - } - else { - cleanUpSSR(); - } - } - const teleports = {}; - for (const key in active) { - const config = this.config[key] || {}; - let renderedNodes = renderMeta({ isSSR, metainfo: active, slots }, key, active[key], config); - if (!renderedNodes) { - continue; - } - if (!isArray(renderedNodes)) { - renderedNodes = [renderedNodes]; - } - let defaultTo = key !== 'base' && active[key].to; - if (!defaultTo && 'to' in config) { - defaultTo = config.to; - } - if (!defaultTo && 'attributesFor' in config) { - defaultTo = key; - } - for (const { to, vnode } of renderedNodes) { - addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); - } - } - if (slots) { - for (const slotName in slots) { - const tagName = slotName === 'default' ? 'head' : slotName; - // Only teleport the contents of head/body slots - if (tagName !== 'head' && tagName !== 'body') { - continue; - } - const slot = slots[slotName]; - if (isFunction(slot)) { - addVnode(this.isSSR, teleports, tagName, slot({ metainfo: active })); - } - } - } - return Object.keys(teleports).map((to) => { - const teleport = teleports[to]; - return vue.h(vue.Teleport, { to }, teleport); - }); - } + if (!isSSR) { + // Comments shouldnt have any use on the client as they are not reactive anyway + nodes.forEach(function (vnode, idx) { + if (vnode.type === vue.Comment) { + nodes.splice(idx, 1); + } + }); // only add ssrAttribute's for real meta tags + } else if (!to.endsWith('Attrs')) { + nodes.forEach(function (vnode) { + if (!vnode.props) { + vnode.props = {}; + } + + vnode.props[ssrAttribute] = true; + }); + } + + if (!teleports[to]) { + teleports[to] = []; + } + + (_teleports$to = teleports[to]).push.apply(_teleports$to, _toConsumableArray__default(nodes)); } +var createMetaManager = function createMetaManager() { + var isSSR = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var config = arguments.length > 1 ? arguments[1] : undefined; + var resolver = arguments.length > 2 ? arguments[2] : undefined; + return MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); +}; +var MetaManager = /*#__PURE__*/function () { + function MetaManager(isSSR, config, target, resolver) { + _classCallCheck__default(this, MetaManager); + + _defineProperty__default(this, "isSSR", false); + + _defineProperty__default(this, "config", void 0); + + _defineProperty__default(this, "target", void 0); + + _defineProperty__default(this, "resolver", void 0); + + _defineProperty__default(this, "ssrCleanedUp", false); + + this.isSSR = isSSR; + this.config = config; + this.target = target; + + if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { + this.resolver = resolver; + } + } + + _createClass__default(MetaManager, [{ + key: "install", + value: function install(app) { + app.component('Metainfo', Metainfo); + app.config.globalProperties.$metaManager = this; + app.provide(metaActiveKey, this.target.context.active); + } + }, { + key: "addMeta", + value: function addMeta(metadata, vm) { + var _this = this; + + if (!vm) { + vm = vue.getCurrentInstance() || undefined; + } + + var metaGuards = { + removed: [] + }; + var resolveContext = { + vm: vm + }; + var resolver = this.resolver; + + if (resolver && resolver.setup) { + resolver.setup(resolveContext); + } // TODO: optimize initial compute (once) + + + var meta = this.target.addSource(metadata, resolveContext, true); + + var onRemoved = function onRemoved(removeGuard) { + return metaGuards.removed.push(removeGuard); + }; + + var unmount = function unmount(ignoreGuards) { + return _this.unmount(!!ignoreGuards, meta, metaGuards, vm); + }; + + if (vm) { + vue.onUnmounted(unmount); + } + + return { + meta: meta, + onRemoved: onRemoved, + unmount: unmount + }; + } + }, { + key: "unmount", + value: function unmount(ignoreGuards, meta, metaGuards, vm) { + var _this2 = this; + + if (vm) { + var $el = vm.proxy.$el; // Wait for element to be removed from DOM + + if ($el && $el.offsetParent) { + var observer = new MutationObserver(function (records) { + var _iterator = _createForOfIteratorHelper(records), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var removedNodes = _step.value.removedNodes; + + if (!removedNodes) { + continue; + } + + removedNodes.forEach(function (el) { + if (el === $el && observer) { + observer.disconnect(); + observer = undefined; + + _this2.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }); + observer.observe($el.parentNode, { + childList: true + }); + return; + } + } + + this.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }, { + key: "reallyUnmount", + value: function () { + var _reallyUnmount = _asyncToGenerator__default( /*#__PURE__*/_regeneratorRuntime__default.mark(function _callee(ignoreGuards, meta, metaGuards) { + return _regeneratorRuntime__default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + this.target.delSource(meta); + + if (!(!ignoreGuards && metaGuards)) { + _context.next = 4; + break; + } + + _context.next = 4; + return Promise.all(metaGuards.removed.map(function (removeGuard) { + return removeGuard(); + })); + + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function reallyUnmount(_x, _x2, _x3) { + return _reallyUnmount.apply(this, arguments); + } + + return reallyUnmount; + }() + }, { + key: "render", + value: function render() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + slots = _ref.slots; + + var active = this.target.context.active; // TODO: clean this method + + var isSSR = this.isSSR; // cleanup ssr tags if not yet done + + if (!isSSR && !this.ssrCleanedUp) { + this.ssrCleanedUp = true; + + var cleanUpSSR = function cleanUpSSR() { + var ssrTags = document.querySelectorAll("[".concat(ssrAttribute, "]")); + + if (ssrTags && ssrTags.length) { + ssrTags.forEach(function (el) { + return el.parentNode && el.parentNode.removeChild(el); + }); + } + }; + + if (document.readyState === 'loading') { + // Listen for DOM loaded because tags in the body couldnt + // have loaded yet once the manager does it first render + // (preferable there should only be one meta render on hydration) + window.addEventListener('DOMContentLoaded', cleanUpSSR, { + once: true + }); + } else { + cleanUpSSR(); + } + } + + var teleports = {}; + + for (var key in active) { + var config = this.config[key] || {}; + var renderedNodes = renderMeta({ + isSSR: isSSR, + metainfo: active, + slots: slots + }, key, active[key], config); + + if (!renderedNodes) { + continue; + } + + if (!isArray(renderedNodes)) { + renderedNodes = [renderedNodes]; + } + + var defaultTo = key !== 'base' && active[key].to; + + if (!defaultTo && 'to' in config) { + defaultTo = config.to; + } + + if (!defaultTo && 'attributesFor' in config) { + defaultTo = key; + } + + var _iterator2 = _createForOfIteratorHelper(renderedNodes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _step2.value, + to = _step2$value.to, + vnode = _step2$value.vnode; + addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + if (slots) { + for (var slotName in slots) { + var tagName = slotName === 'default' ? 'head' : slotName; // Only teleport the contents of head/body slots + + if (tagName !== 'head' && tagName !== 'body') { + continue; + } + + var slot = slots[slotName]; + + if (isFunction(slot)) { + addVnode(this.isSSR, teleports, tagName, slot({ + metainfo: active + })); + } + } + } + + return Object.keys(teleports).map(function (to) { + var teleport = teleports[to]; + return vue.h(vue.Teleport, { + to: to + }, teleport); + }); + } + }]); + + return MetaManager; +}(); + +_defineProperty__default(MetaManager, "create", function (isSSR, config, resolver) { + var resolve = function resolve(options, contexts, active, key, pathSegments) { + if (isFunction(resolver)) { + return resolver(options, contexts, active, key, pathSegments); + } + + return resolver.resolve(options, contexts, active, key, pathSegments); + }; + + var active = vue.reactive({}); + var mergedObject = createMergedObject(resolve, active); // TODO: validate resolver + + var manager = new MetaManager(isSSR, config, mergedObject, resolver); + return manager; +}); + +var defaultOptions = { + keyName: 'metaInfo' +}; +var createMixin = function createMixin(options) { + return { + created: function created() { + var instance = vue.getCurrentInstance(); + + if (!(instance !== null && instance !== void 0 && instance.type) || !(options.keyName in instance.type)) { + return; + } + + var metaInfo = instance.type[options.keyName]; + + if (isFunction(metaInfo)) { + var computedMetaInfo = vue.computed(metaInfo.bind(this)); + useMeta(computedMetaInfo); + } else { + useMeta(metaInfo); + } + } + }; +}; +var install = function install(app) { + var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; -const defaultOptions = { - keyName: 'metaInfo' -}; -const createMixin = options => ({ - created() { - const instance = vue.getCurrentInstance(); - if (!instance?.type || !(options.keyName in instance.type)) { - return; - } - const metaInfo = instance.type[options.keyName]; - if (isFunction(metaInfo)) { - const computedMetaInfo = vue.computed(metaInfo.bind(this)); - useMeta(computedMetaInfo); - } - else { - useMeta(metaInfo); - } - } -}); -const install = (app, _options = {}) => { - const options = Object.assign({}, defaultOptions, _options); - app.mixin(createMixin(options)); + var options = Object.assign({}, defaultOptions, _options); + app.mixin(createMixin(options)); }; exports.createMetaManager = createMetaManager; diff --git a/dist/vue-meta.cjs.prod.js b/dist/vue-meta.cjs.prod.js index de10c8dc..1ace9a60 100644 --- a/dist/vue-meta.cjs.prod.js +++ b/dist/vue-meta.cjs.prod.js @@ -10,42 +10,71 @@ Object.defineProperty(exports, '__esModule', { value: true }); +var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator'); +var _classCallCheck = require('@babel/runtime/helpers/classCallCheck'); +var _createClass = require('@babel/runtime/helpers/createClass'); +var _defineProperty = require('@babel/runtime/helpers/defineProperty'); +var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray'); +var _regeneratorRuntime = require('@babel/runtime/regenerator'); var vue = require('vue'); +var _typeof = require('@babel/runtime/helpers/typeof'); +var _slicedToArray = require('@babel/runtime/helpers/slicedToArray'); -const resolveOption = (predicament, initialValue) => (options, contexts) => { - let resolvedIndex = -1; - contexts.reduce((acc, context, index) => { - const retval = predicament(acc, context); - if (retval !== acc) { - resolvedIndex = index; - return retval; - } - return acc; - }, initialValue); - if (resolvedIndex > -1) { - return options[resolvedIndex]; - } +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } + +var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator); +var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck); +var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass); +var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); +var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); +var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime); +var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof); +var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); + +var resolveOption = function resolveOption(predicament, initialValue) { + return function (options, contexts) { + var resolvedIndex = -1; + contexts.reduce(function (acc, context, index) { + var retval = predicament(acc, context); + + if (retval !== acc) { + resolvedIndex = index; + return retval; + } + + return acc; + }, initialValue); + + if (resolvedIndex > -1) { + return options[resolvedIndex]; + } + }; +}; + +var setup = function setup(context) { + var depth = 0; + + if (context.vm) { + var vm = context.vm; + + do { + if (vm.parent) { + depth++; + vm = vm.parent; + } + } while (vm && vm.parent && vm !== vm.root); + } + + context.depth = depth; }; +var resolve = resolveOption(function (currentValue, context) { + var depth = context.depth; + + if (!currentValue || depth > currentValue) { + return depth; + } -const setup = (context) => { - let depth = 0; - if (context.vm) { - let { vm } = context; - do { - if (vm.parent) { - depth++; - vm = vm.parent; - } - } while (vm && vm.parent && vm !== vm.root); - } - context.depth = depth; -}; -const resolve = resolveOption((currentValue, context) => { - const { depth } = context; - if (!currentValue || depth > currentValue) { - return depth; - } - return currentValue; + return currentValue; }); var defaultResolver = /*#__PURE__*/Object.freeze({ @@ -54,105 +83,98 @@ var defaultResolver = /*#__PURE__*/Object.freeze({ resolve: resolve }); -const defaultConfig = { - body: { - tag: 'script', - to: 'body' - }, - base: { - valueAttribute: 'href' - }, - charset: { - tag: 'meta', - nameless: true, - valueAttribute: 'charset' - }, - description: { - tag: 'meta' - }, - og: { - group: true, - namespacedAttribute: true, - tag: 'meta', - keyAttribute: 'property' - }, - twitter: { - group: true, - namespacedAttribute: true, - tag: 'meta' - }, - htmlAttrs: { - attributesFor: 'html' - }, - headAttrs: { - attributesFor: 'head' - }, - bodyAttrs: { - attributesFor: 'body' - } +var defaultConfig = { + body: { + tag: 'script', + to: 'body' + }, + base: { + valueAttribute: 'href' + }, + charset: { + tag: 'meta', + nameless: true, + valueAttribute: 'charset' + }, + description: { + tag: 'meta' + }, + og: { + group: true, + namespacedAttribute: true, + tag: 'meta', + keyAttribute: 'property' + }, + twitter: { + group: true, + namespacedAttribute: true, + tag: 'meta' + }, + htmlAttrs: { + attributesFor: 'html' + }, + headAttrs: { + attributesFor: 'head' + }, + bodyAttrs: { + attributesFor: 'body' + } }; /* * This is a fixed config for real HTML tags - */ -const tags = { - title: { - attributes: false - }, - base: { - contentAsAttribute: true, - attributes: ['href', 'target'] - }, - meta: { - contentAsAttribute: true, - keyAttribute: 'name', - attributes: ['content', 'name', 'http-equiv', 'charset'] - }, - link: { - contentAsAttribute: true, - attributes: [ - 'href', - 'crossorigin', - 'rel', - 'media', - 'integrity', - 'hreflang', - 'type', - 'referrerpolicy', - 'sizes', - 'imagesrcset', - 'imagesizes', - 'as', - 'color' - ] - }, - style: { - attributes: ['media'] - }, - script: { - attributes: [ - 'src', - 'type', - 'nomodule', - 'async', - 'defer', - 'crossorigin', - 'integrity', - 'referrerpolicy' - ] - }, - noscript: { - attributes: false - } + */ +var tags = { + title: { + attributes: false + }, + base: { + contentAsAttribute: true, + attributes: ['href', 'target'] + }, + meta: { + contentAsAttribute: true, + keyAttribute: 'name', + attributes: ['content', 'name', 'http-equiv', 'charset'] + }, + link: { + contentAsAttribute: true, + attributes: ['href', 'crossorigin', 'rel', 'media', 'integrity', 'hreflang', 'type', 'referrerpolicy', 'sizes', 'imagesrcset', 'imagesizes', 'as', 'color'] + }, + style: { + attributes: ['media'] + }, + script: { + attributes: ['src', 'type', 'nomodule', 'async', 'defer', 'crossorigin', 'integrity', 'referrerpolicy'] + }, + noscript: { + attributes: false + } }; -function getTagConfigItem(tagOrName, key) { - for (const name of tagOrName) { - const tag = tags[name]; - if (name && tag) { - return tag[key]; - } - } +function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(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$5(o, minLen); } + +function _arrayLikeToArray$5(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 getTagConfigItem(tagOrName, key) { + var _iterator = _createForOfIteratorHelper$5(tagOrName), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var name = _step.value; + var tag = tags[name]; + + if (name && tag) { + return tag[key]; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } } /** @@ -170,788 +192,1256 @@ const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const isPlainObject = (val) => toTypeString(val) === '[object Object]'; -// https://github.com/microsoft/TypeScript/issues/1863 -const IS_PROXY = Symbol('kIsProxy'); -const PROXY_SOURCES = Symbol('kProxySources'); -const PROXY_TARGET = Symbol('kProxyTarget'); -const RESOLVE_CONTEXT = Symbol('kResolveContext'); - -// See: https://github.com/vuejs/vue-next/blob/08b4e8815da4e8911058ccbab986bea6365c3352/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts -function clone(v) { - if (isArray(v)) { - return v.map(clone); - } - if (isObject(v)) { - const res = {}; - for (const key in v) { - // never clone the context - if (key === 'context') { - res[key] = v[key]; - } - else { - res[key] = clone(v[key]); - } - } - return res; - } - return v; +// https://github.com/microsoft/TypeScript/issues/1863 +var IS_PROXY = Symbol('kIsProxy'); +var PROXY_SOURCES = Symbol('kProxySources'); +var PROXY_TARGET = Symbol('kProxyTarget'); +var RESOLVE_CONTEXT = Symbol('kResolveContext'); + +function clone(v) { + if (isArray(v)) { + return v.map(clone); + } + + if (isObject(v)) { + var res = {}; + + for (var key in v) { + // never clone the context + if (key === 'context') { + res[key] = v[key]; + } else { + res[key] = clone(v[key]); + } + } + + return res; + } + + return v; } -const pluck = (collection, key, callback) => { - const plucked = []; - for (const row of collection) { - if (row && key in row) { - plucked.push(row[key]); - if (callback) { - callback(row); - } - } - } - return plucked; +function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(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$4(o, minLen); } + +function _arrayLikeToArray$4(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; } + +var pluck = function pluck(collection, key, callback) { + var plucked = []; + + var _iterator = _createForOfIteratorHelper$4(collection), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var row = _step.value; + + if (row && key in row) { + plucked.push(row[key]); + + if (callback) { + callback(row); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return plucked; }; -const allKeys = (source, ...sources) => { - const keys = source ? Object.keys(source) : []; - if (sources) { - for (const source of sources) { - if (!source || !isObject(source)) { - continue; - } - for (const key in source) { - if (!keys.includes(key)) { - keys.push(key); - } - } - } - } - // TODO: add check for consistent types for each key (dev only) - return keys; -}; -const recompute = (context, path = [], target, sources) => { - const setTargetAndSources = !target && !sources; - if (setTargetAndSources) { - ({ active: target, sources } = context); - if (path.length) { - for (let i = 0; i < path.length; i++) { - const seg = path[i]; - if (!target || !target[seg]) { - return; - } - target = target[seg]; - sources = sources.map(source => source[seg]).filter(Boolean); - } - } - } - if (!target || !sources) { - return; - } - const keys = allKeys(...sources); - // Clean up properties that dont exists anymore - const targetKeys = Object.keys(target); - for (const key of targetKeys) { - if (!keys.includes(key)) { - delete target[key]; - } - } - for (const key of keys) { - // This assumes consistent types usages for keys across sources - // @ts-ignore - let isObject = false; - for (let i = 0; i < sources.length; i++) { - const source = sources[i]; - if (source && key in source && source[key] !== undefined) { - isObject = isPlainObject(source[key]); - break; - } - } - if (isObject) { - if (!target[key]) { - target[key] = {}; - } - const keySources = []; - for (const source of sources) { - if (key in source) { - // @ts-ignore - keySources.push(source[key]); - } - } - recompute(context, [...path, key], target[key], keySources); - continue; - } - // Ensure the target is an array if source is an array and target is empty - // @ts-ignore - if (!target[key] && isArray(sources[0][key])) { - target[key] = []; - } - const keyContexts = []; - const keySources = pluck(sources, key, source => keyContexts.push(source[RESOLVE_CONTEXT])); - let resolved = context.resolve(keySources, keyContexts, target[key], key, path); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - target[key] = resolved; - } +var debugFn = function debugFn(logFn) { + var setChildFns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fn = function fn() { + try { + throw new Error('DEBUG'); + } catch (err) { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logFn.apply(void 0, args.concat(['\n', err])); + } + }; + + if (setChildFns) { + fn.warn = debugFn(console.warn); // eslint-disable-line no-console + + fn.error = debugFn(console.error); // eslint-disable-line no-console + } + + return fn; }; +debugFn(console.log, true); // eslint-disable-line no-console + +function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(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$3(o, minLen); } + +function _arrayLikeToArray$3(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; } +var allKeys = function allKeys(source) { + var keys = source ? Object.keys(source) : []; + + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (sources) { + var _iterator = _createForOfIteratorHelper$3(sources), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _source = _step.value; + + if (!_source || !isObject(_source)) { + continue; + } + + for (var key in _source) { + if (!keys.includes(key)) { + keys.push(key); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } // TODO: add check for consistent types for each key (dev only) -const createProxy = (context, target, resolveContext, pathSegments = []) => { - const handler = createHandler(context, resolveContext, pathSegments); - const proxy = vue.markRaw(new Proxy(target, handler)); - if (!pathSegments.length && context.sources) { - context.sources.push(proxy); - } - return proxy; -}; -const createHandler = (context, resolveContext, pathSegments = []) => ({ - get: (target, key, receiver) => { - if (key === IS_PROXY) { - return true; - } - if (key === PROXY_SOURCES) { - return context.sources; - } - if (key === PROXY_TARGET) { - return target; - } - if (key === RESOLVE_CONTEXT) { - return resolveContext; - } - let value = Reflect.get(target, key, receiver); - if (!isObject(value)) { - return value; - } - // Also return a merge proxy for nested objects - if (!value[IS_PROXY]) { - const keyPath = [...pathSegments, key]; - value = createProxy(context, value, resolveContext, keyPath); - Reflect.set(target, key, value); - } - return value; - }, - set: (target, key, value) => { - const success = Reflect.set(target, key, value); - // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) - if (success) { - const isArrayItem = isArray(target); - let hasArrayParent = false; - let { sources: proxies, active } = context; - let activeSegmentKey; - let index = 0; - for (const segment of pathSegments) { - proxies = pluck(proxies, segment); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - if (isArray(active)) { - hasArrayParent = true; - } - active = active[segment]; - index++; - } - if (hasArrayParent) { - // TODO: fix that we dont have to recompute the full merged object - // we should only have to recompute the branch that has changed - // but there is an issue here with supporting both arrays of strings - // as collections (parent vs parent of parent we need to trigger the - // update from) - recompute(context); - return success; - } - else if (isPlainObject(value)) { - // if an object was assigned to this key make sure to recompute all - // of its individual properies - recompute(context, pathSegments); - return success; - } - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - // Ensure to clone if value is an object, cause sources is an array of - // the sourceProxies and not the sources so we could trigger an endless loop when - // updating a prop on an obj as the prop on the active object refers to - // a prop on a proxy - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) - return success; - }, - deleteProperty: (target, key) => { - const success = Reflect.deleteProperty(target, key); - // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) - if (success) { - const isArrayItem = isArray(target); - let activeSegmentKey; - let proxies = context.sources; - let active = context.active; - let index = 0; - for (const segment of pathSegments) { - // @ts-ignore - proxies = proxies.map(proxy => proxy && proxy[segment]); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - active = active[segment]; - index++; - } - // Check if the key still exists in one of the sourceProxies, - // if so resolve the new value, if not remove the key - if (proxies.some(proxy => proxy && (key in proxy))) { - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', resolved) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - else { - delete active[key]; - } - } - return success; - } -}); -const createMergedObject = (resolve, active) => { - const sources = []; - const context = { - active, - resolve, - sources - }; - const compute = () => recompute(context); - return { - context, - compute, - addSource: (source, resolveContext, recompute = false) => { - const proxy = createProxy(context, source, resolveContext || {}); - if (recompute) { - compute(); - } - return proxy; - }, - delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); - if (index > -1) { - sources.splice(index, 1); - if (recompute) { - compute(); - } - return true; - } - return false; - } - }; + return keys; }; +var recompute = function recompute(context) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var target = arguments.length > 2 ? arguments[2] : undefined; + var sources = arguments.length > 3 ? arguments[3] : undefined; + var setTargetAndSources = !target && !sources; + + if (setTargetAndSources) { + target = context.active; + sources = context.sources; + + if (path.length) { + var _loop = function _loop(i) { + var seg = path[i]; + + if (!target || !target[seg]) { + + return { + v: void 0 + }; + } + + target = target[seg]; + sources = sources.map(function (source) { + return source[seg]; + }).filter(Boolean); + }; + + for (var i = 0; i < path.length; i++) { + var _ret = _loop(i); + + if (_typeof__default(_ret) === "object") return _ret.v; + } + } + } + + if (!target || !sources) { + return; + } + + var keys = allKeys.apply(void 0, _toConsumableArray__default(sources)); // Clean up properties that dont exists anymore + + var targetKeys = Object.keys(target); + + for (var _i = 0, _targetKeys = targetKeys; _i < _targetKeys.length; _i++) { + var key = _targetKeys[_i]; + + if (!keys.includes(key)) { + delete target[key]; + } + } + + var _iterator2 = _createForOfIteratorHelper$3(keys), + _step2; + + try { + var _loop2 = function _loop2() { + var key = _step2.value; + // This assumes consistent types usages for keys across sources + // @ts-ignore + var isObject = false; + + for (var _i2 = 0; _i2 < sources.length; _i2++) { + var source = sources[_i2]; + + if (source && key in source && source[key] !== undefined) { + isObject = isPlainObject(source[key]); + break; + } + } + + if (isObject) { + if (!target[key]) { + target[key] = {}; + } + + var _keySources = []; + + var _iterator3 = _createForOfIteratorHelper$3(sources), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _source2 = _step3.value; + + if (key in _source2) { + // @ts-ignore + _keySources.push(_source2[key]); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + recompute(context, [].concat(_toConsumableArray__default(path), [key]), target[key], _keySources); + return "continue"; + } // Ensure the target is an array if source is an array and target is empty + // @ts-ignore + + + if (!target[key] && isArray(sources[0][key])) { + target[key] = []; + } + + var keyContexts = []; + var keySources = pluck(sources, key, function (source) { + return keyContexts.push(source[RESOLVE_CONTEXT]); + }); + var resolved = context.resolve(keySources, keyContexts, target[key], key, path); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } + + target[key] = resolved; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret2 = _loop2(); + + if (_ret2 === "continue") continue; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } +}; + +function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(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$2(o, minLen); } + +function _arrayLikeToArray$2(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; } +var createProxy = function createProxy(context, target, resolveContext) { + var pathSegments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + var handler = createHandler(context, resolveContext, pathSegments); + var proxy = vue.markRaw(new Proxy(target, handler)); + + if (!pathSegments.length && context.sources) { + context.sources.push(proxy); + } + + return proxy; +}; +var createHandler = function createHandler(context, resolveContext) { + var pathSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + return { + get: function get(target, key, receiver) { + if (key === IS_PROXY) { + return true; + } + + if (key === PROXY_SOURCES) { + return context.sources; + } + + if (key === PROXY_TARGET) { + return target; + } + + if (key === RESOLVE_CONTEXT) { + return resolveContext; + } + + var value = Reflect.get(target, key, receiver); + + if (!isObject(value)) { + return value; + } // Also return a merge proxy for nested objects + + + if (!value[IS_PROXY]) { + var keyPath = [].concat(_toConsumableArray__default(pathSegments), [key]); + value = createProxy(context, value, resolveContext, keyPath); + Reflect.set(target, key, value); + } + + return value; + }, + set: function set(target, key, value) { + var success = Reflect.set(target, key, value); // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) + + if (success) { + var isArrayItem = isArray(target); + var hasArrayParent = false; + var proxies = context.sources, + active = context.active; + var activeSegmentKey; + var index = 0; + + var _iterator = _createForOfIteratorHelper$2(pathSegments), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var segment = _step.value; + proxies = pluck(proxies, segment); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + break; + } + + if (isArray(active)) { + hasArrayParent = true; + } + + active = active[segment]; + index++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + if (hasArrayParent) { + // TODO: fix that we dont have to recompute the full merged object + // we should only have to recompute the branch that has changed + // but there is an issue here with supporting both arrays of strings + // as collections (parent vs parent of parent we need to trigger the + // update from) + recompute(context); + return success; + } else if (isPlainObject(value)) { + // if an object was assigned to this key make sure to recompute all + // of its individual properies + recompute(context, pathSegments); + return success; + } + + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); // Ensure to clone if value is an object, cause sources is an array of + // the sourceProxies and not the sources so we could trigger an endless loop when + // updating a prop on an obj as the prop on the active object refers to + // a prop on a proxy + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) + + + return success; + }, + deleteProperty: function deleteProperty(target, key) { + var success = Reflect.deleteProperty(target, key); // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) + + if (success) { + var isArrayItem = isArray(target); + var activeSegmentKey; + var proxies = context.sources; + var active = context.active; + var index = 0; + + var _iterator2 = _createForOfIteratorHelper$2(pathSegments), + _step2; + + try { + var _loop = function _loop() { + var segment = _step2.value; + // @ts-ignore + proxies = proxies.map(function (proxy) { + return proxy && proxy[segment]; + }); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + return "break"; + } + + active = active[segment]; + index++; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret = _loop(); + + if (_ret === "break") break; + } // Check if the key still exists in one of the sourceProxies, + // if so resolve the new value, if not remove the key + + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + if (proxies.some(function (proxy) { + return proxy && key in proxy; + })) { + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', resolved) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } else { + delete active[key]; + } + } + + return success; + } + }; +}; + +var createMergedObject = function createMergedObject(resolve, active) { + var sources = []; + var context = { + active: active, + resolve: resolve, + sources: sources + }; + + var compute = function compute() { + return recompute(context); + }; + + return { + context: context, + compute: compute, + addSource: function addSource(source, resolveContext) { + var recompute = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var proxy = createProxy(context, source, resolveContext || {}); + + if (recompute) { + compute(); + } + + return proxy; + }, + delSource: function delSource(sourceOrProxy) { + var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var index = sources.findIndex(function (source) { + return source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy; + }); + + if (index > -1) { + sources.splice(index, 1); + + if (recompute) { + compute(); + } + + return true; + } + + return false; + } + }; +}; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(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$1(o, minLen); } + +function _arrayLikeToArray$1(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; } +var cachedElements = {}; +function renderMeta(context, key, data, config) { + // console.info('renderMeta', key, data, config) + if ('attributesFor' in config) { + return renderAttributes(context, key, data, config); + } + + if ('group' in config) { + return renderGroup(context, key, data, config); + } + + return renderTag(context, key, data, config); +} +function renderGroup(context, key, data, config) { + // console.info('renderGroup', key, data, config) + if (isArray(data)) { + + + return []; + } -const cachedElements = {}; -function renderMeta(context, key, data, config) { - // console.info('renderMeta', key, data, config) - if ('attributesFor' in config) { - return renderAttributes(context, key, data, config); - } - if ('group' in config) { - return renderGroup(context, key, data, config); - } - return renderTag(context, key, data, config); -} -function renderGroup(context, key, data, config) { - // console.info('renderGroup', key, data, config) - if (isArray(data)) { - // config.attributes = getConfigKey([key, config.tag], 'attributes', config) - return []; - } - return Object.keys(data) - .map((childKey) => { - const groupConfig = { - group: key, - data - }; - if (config.namespaced) { - groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; - } - else if (config.namespacedAttribute) { - const namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; - groupConfig.fullName = `${namespace}:${childKey}`; - groupConfig.slotName = `${namespace}(${childKey})`; - } - return renderTag(context, key, data[childKey], config, groupConfig); - }) - .filter(Boolean) - .flat(); -} -function renderTag(context, key, data, config = {}, groupConfig) { - // console.info('renderTag', key, data, config, groupConfig) - const contentAttributes = ['content', 'json', 'rawContent']; - const getTagConfig = (key) => getTagConfigItem([tag, config.tag], key); - if (isArray(data)) { - return data - .map((child) => { - return renderTag(context, key, child, config, groupConfig); - }) - .filter(Boolean) - .flat(); - } - const { tag = config.tag || key } = data; - let content = ''; - let hasChilds = false; - let isRaw = false; - if (isString(data)) { - content = data; - } - else if (data.children && isArray(data.children)) { - hasChilds = true; - content = data.children.map((child) => { - const data = renderTag(context, key, child, config, groupConfig); - if (isArray(data)) { - return data.map(({ vnode }) => vnode); - } - return data && data.vnode; - }); - } - else { - let i = 0; - for (const contentAttribute of contentAttributes) { - if (!content && data[contentAttribute]) { - if (i === 1) { - content = JSON.stringify(data[contentAttribute]); - } - else { - content = data[contentAttribute]; - } - isRaw = i > 1; - break; - } - i++; - } - } - const fullName = (groupConfig && groupConfig.fullName) || key; - const slotName = (groupConfig && groupConfig.slotName) || key; - let { attrs: attributes } = data; - if (!attributes && typeof data === 'object') { - attributes = { ...data }; - delete attributes.tag; - delete attributes.children; - delete attributes.to; - // cleanup all content attributes - for (const attr of contentAttributes) { - delete attributes[attr]; - } - } - else if (!attributes) { - attributes = {}; - } - if (hasChilds) { - content = getSlotContent(context, slotName, content, data); - } - else { - const contentAsAttribute = !!getTagConfig('contentAsAttribute'); - let { valueAttribute } = config; - if (!valueAttribute && contentAsAttribute) { - const [tagAttribute] = getTagConfig('attributes'); - valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; - } - if (!valueAttribute) { - content = getSlotContent(context, slotName, content, data); - } - else { - const { nameless } = config; - if (!nameless) { - const keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); - if (keyAttribute) { - attributes[keyAttribute] = fullName; - } - } - attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); - content = ''; - } - } - const finalTag = groupConfig && groupConfig.tagNamespace - ? `${groupConfig.tagNamespace}:${tag}` - : tag; - if (finalTag === 'title' && !context.isSSR) { - document.title = content; - return; - } - // console.info('FINAL TAG', finalTag) - // console.log(' ATTRIBUTES', attributes) - // console.log(' CONTENT', content) - // console.log(data, attributes, config) - if (isRaw && content) { - attributes.innerHTML = content; - } - // Ignore empty string content - const vnode = vue.h(finalTag, attributes, content || undefined); - return { - to: data.to, - vnode - }; -} -function renderAttributes(context, key, data, config) { - // console.info('renderAttributes', key, data, config) - const { attributesFor } = config; - if (!attributesFor || !data) { - return; - } - if (context.isSSR) { - // render attributes in a placeholder vnode so Vue - // will render the string for us - return { - to: '', - vnode: vue.h(`ssr-${attributesFor}`, data) - }; - } - if (!cachedElements[attributesFor]) { - const [el, el2] = Array.from(document.querySelectorAll(attributesFor)); - cachedElements[attributesFor] = { - el, - attrs: [] - }; - } - const { el, attrs } = cachedElements[attributesFor]; - for (const attr in data) { - let content = getSlotContent(context, `${key}(${attr})`, data[attr], data); - if (isArray(content)) { - content = content.join(','); - } - el.setAttribute(attr, content || ''); - if (!attrs.includes(attr)) { - attrs.push(attr); - } - } - const attrsToRemove = attrs.filter(attr => !data[attr]); - for (const attr of attrsToRemove) { - el.removeAttribute(attr); - } -} -function getSlotContent({ metainfo, slots }, slotName, content, groupConfig) { - const slot = slots && slots[slotName]; - if (!slot || !isFunction(slot)) { - return content; - } - const slotScopeProps = { - content, - metainfo - }; - if (groupConfig && groupConfig.group) { - const { group, data } = groupConfig; - slotScopeProps[group] = data; - } - const slotContent = slot(slotScopeProps); - if (slotContent && slotContent.length) { - const { children } = slotContent[0]; - return children ? children.toString() : ''; - } - return content; + return Object.keys(data).map(function (childKey) { + var groupConfig = { + group: key, + data: data + }; + + if (config.namespaced) { + groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; + } else if (config.namespacedAttribute) { + var namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; + groupConfig.fullName = "".concat(namespace, ":").concat(childKey); + groupConfig.slotName = "".concat(namespace, "(").concat(childKey, ")"); + } + + return renderTag(context, key, data[childKey], config, groupConfig); + }).filter(Boolean).flat(); +} +function renderTag(context, key, data) { + var config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var groupConfig = arguments.length > 4 ? arguments[4] : undefined; + // console.info('renderTag', key, data, config, groupConfig) + var contentAttributes = ['content', 'json', 'rawContent']; + + var getTagConfig = function getTagConfig(key) { + return getTagConfigItem([tag, config.tag], key); + }; + + if (isArray(data)) { + return data.map(function (child) { + return renderTag(context, key, child, config, groupConfig); + }).filter(Boolean).flat(); + } + + var _data$tag = data.tag, + tag = _data$tag === void 0 ? config.tag || key : _data$tag; + var content = ''; + var hasChilds = false; + var isRaw = false; + + if (isString(data)) { + content = data; + } else if (data.children && isArray(data.children)) { + hasChilds = true; + content = data.children.map(function (child) { + var data = renderTag(context, key, child, config, groupConfig); + + if (isArray(data)) { + return data.map(function (_ref) { + var vnode = _ref.vnode; + return vnode; + }); + } + + return data && data.vnode; + }); + } else { + var i = 0; + + var _iterator = _createForOfIteratorHelper$1(contentAttributes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var contentAttribute = _step.value; + + if (!content && data[contentAttribute]) { + if (i === 1) { + content = JSON.stringify(data[contentAttribute]); + } else { + content = data[contentAttribute]; + } + + isRaw = i > 1; + break; + } + + i++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + var fullName = groupConfig && groupConfig.fullName || key; + var slotName = groupConfig && groupConfig.slotName || key; + var attributes = data.attrs; + + if (!attributes && _typeof__default(data) === 'object') { + attributes = _objectSpread({}, data); + delete attributes.tag; + delete attributes.children; + delete attributes.to; // cleanup all content attributes + + var _iterator2 = _createForOfIteratorHelper$1(contentAttributes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var attr = _step2.value; + delete attributes[attr]; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } else if (!attributes) { + attributes = {}; + } + + if (hasChilds) { + content = getSlotContent(context, slotName, content, data); + } else { + var contentAsAttribute = !!getTagConfig('contentAsAttribute'); + var valueAttribute = config.valueAttribute; + + if (!valueAttribute && contentAsAttribute) { + var _getTagConfig = getTagConfig('attributes'), + _getTagConfig2 = _slicedToArray__default(_getTagConfig, 1), + tagAttribute = _getTagConfig2[0]; + + valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; + } + + if (!valueAttribute) { + content = getSlotContent(context, slotName, content, data); + } else { + var nameless = config.nameless; + + if (!nameless) { + var keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); + + if (keyAttribute) { + attributes[keyAttribute] = fullName; + } + } + + attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); + content = ''; + } + } + + var finalTag = groupConfig && groupConfig.tagNamespace ? "".concat(groupConfig.tagNamespace, ":").concat(tag) : tag; + + if (finalTag === 'title' && !context.isSSR) { + document.title = content; + return; + } // console.info('FINAL TAG', finalTag) + // console.log(' ATTRIBUTES', attributes) + // console.log(' CONTENT', content) + // console.log(data, attributes, config) + + + if (isRaw && content) { + attributes.innerHTML = content; + } // Ignore empty string content + + + var vnode = vue.h(finalTag, attributes, content || undefined); + return { + to: data.to, + vnode: vnode + }; +} +function renderAttributes(context, key, data, config) { + // console.info('renderAttributes', key, data, config) + var attributesFor = config.attributesFor; + + if (!attributesFor || !data) { + return; + } + + if (context.isSSR) { + // render attributes in a placeholder vnode so Vue + // will render the string for us + return { + to: '', + vnode: vue.h("ssr-".concat(attributesFor), data) + }; + } + + if (!cachedElements[attributesFor]) { + var _Array$from = Array.from(document.querySelectorAll(attributesFor)), + _Array$from2 = _slicedToArray__default(_Array$from, 2), + _el = _Array$from2[0]; + _Array$from2[1]; + + cachedElements[attributesFor] = { + el: _el, + attrs: [] + }; + } + + var _cachedElements$attri = cachedElements[attributesFor], + el = _cachedElements$attri.el, + attrs = _cachedElements$attri.attrs; + + for (var attr in data) { + var content = getSlotContent(context, "".concat(key, "(").concat(attr, ")"), data[attr], data); + + if (isArray(content)) { + content = content.join(','); + } + + el.setAttribute(attr, content || ''); + + if (!attrs.includes(attr)) { + attrs.push(attr); + } + } + + var attrsToRemove = attrs.filter(function (attr) { + return !data[attr]; + }); + + var _iterator3 = _createForOfIteratorHelper$1(attrsToRemove), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _attr = _step3.value; + el.removeAttribute(_attr); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } } +function getSlotContent(_ref2, slotName, content, groupConfig) { + var metainfo = _ref2.metainfo, + slots = _ref2.slots; + var slot = slots && slots[slotName]; -const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; -const PolySymbol = (name) => -// vm = vue meta -hasSymbol - ? Symbol(name) - : ('_vm_') + name; -const metaActiveKey = /*#__PURE__*/ PolySymbol('ma'); + if (!slot || !isFunction(slot)) { + return content; + } + + var slotScopeProps = { + content: content, + metainfo: metainfo + }; + + if (groupConfig && groupConfig.group) { + var group = groupConfig.group, + data = groupConfig.data; + slotScopeProps[group] = data; + } + + var slotContent = slot(slotScopeProps); + + if (slotContent && slotContent.length) { + var children = slotContent[0].children; + return children ? children.toString() : ''; + } + + return content; +} + +var hasSymbol = typeof Symbol === 'function' && _typeof__default(Symbol.toStringTag) === 'symbol'; +var PolySymbol = function PolySymbol(name) { + return (// vm = vue meta + hasSymbol ? Symbol(name) : ('_vm_') + name + ); +}; +var metaActiveKey = /*#__PURE__*/PolySymbol('ma'); /** * Apply the differences between newSource & oldSource to target - */ -function applyDifference(target, newSource, oldSource) { - for (const key in newSource) { - if (!(key in oldSource)) { - target[key] = newSource[key]; - continue; - } - if (isObject(target[key])) { - applyDifference(target[key], newSource[key], oldSource[key]); - continue; - } - if (newSource[key] !== oldSource[key]) { - target[key] = newSource[key]; - } - } - for (const key in oldSource) { - if (!newSource || !(key in newSource)) { - delete target[key]; - } - } + */ + +function applyDifference(target, newSource, oldSource) { + for (var key in newSource) { + if (!(key in oldSource)) { + target[key] = newSource[key]; + continue; + } + + if (isObject(target[key])) { + applyDifference(target[key], newSource[key], oldSource[key]); + continue; + } + + if (newSource[key] !== oldSource[key]) { + target[key] = newSource[key]; + } + } + + for (var _key in oldSource) { + if (!newSource || !(_key in newSource)) { + delete target[_key]; + } + } } -function getCurrentManager(vm) { - if (!vm) { - vm = vue.getCurrentInstance() || undefined; - } - if (!vm) { - return undefined; - } - return vm.appContext.config.globalProperties.$metaManager; -} -function useMeta(source, manager) { - const vm = vue.getCurrentInstance() || undefined; - if (!manager && vm) { - manager = getCurrentManager(vm); - } - if (!manager) { - throw new Error('No manager or current instance'); - } - if (vue.isProxy(source)) { - vue.watch(source, (newSource, oldSource) => { - applyDifference(metaProxy.meta, newSource, oldSource); - }); - source = source.value; - } - const metaProxy = manager.addMeta(source, vm); - return metaProxy; -} -function useActiveMeta() { - return vue.inject(metaActiveKey); +function getCurrentManager(vm) { + if (!vm) { + vm = vue.getCurrentInstance() || undefined; + } + + if (!vm) { + return undefined; + } + + return vm.appContext.config.globalProperties.$metaManager; } +function useMeta(source, manager) { + var vm = vue.getCurrentInstance() || undefined; + + if (!manager && vm) { + manager = getCurrentManager(vm); + } + + if (!manager) { + throw new Error('No manager or current instance'); + } -const MetainfoImpl = vue.defineComponent({ - name: 'Metainfo', - inheritAttrs: false, - setup(_, { slots }) { - return () => { - const manager = getCurrentManager(); - if (!manager) { - return; - } - return manager.render({ slots }); - }; - } -}); -const Metainfo = MetainfoImpl; - -const ssrAttribute = 'data-vm-ssr'; -function addVnode(isSSR, teleports, to, vnodes) { - const nodes = (isArray(vnodes) ? vnodes : [vnodes]); - if (!isSSR) { - // Comments shouldnt have any use on the client as they are not reactive anyway - nodes.forEach((vnode, idx) => { - if (vnode.type === vue.Comment) { - nodes.splice(idx, 1); - } - }); - // only add ssrAttribute's for real meta tags - } - else if (!to.endsWith('Attrs')) { - nodes.forEach((vnode) => { - if (!vnode.props) { - vnode.props = {}; - } - vnode.props[ssrAttribute] = true; - }); - } - if (!teleports[to]) { - teleports[to] = []; - } - teleports[to].push(...nodes); -} -const createMetaManager = (isSSR = false, config, resolver) => MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); -class MetaManager { - isSSR = false; - config; - target; - resolver; - ssrCleanedUp = false; - constructor(isSSR, config, target, resolver) { - this.isSSR = isSSR; - this.config = config; - this.target = target; - if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { - this.resolver = resolver; - } - } - static create = (isSSR, config, resolver) => { - const resolve = (options, contexts, active, key, pathSegments) => { - if (isFunction(resolver)) { - return resolver(options, contexts, active, key, pathSegments); - } - return resolver.resolve(options, contexts, active, key, pathSegments); - }; - const active = vue.reactive({}); - const mergedObject = createMergedObject(resolve, active); - // TODO: validate resolver - const manager = new MetaManager(isSSR, config, mergedObject, resolver); - return manager; - }; - install(app) { - app.component('Metainfo', Metainfo); - app.config.globalProperties.$metaManager = this; - app.provide(metaActiveKey, this.target.context.active); - } - addMeta(metadata, vm) { - if (!vm) { - vm = vue.getCurrentInstance() || undefined; - } - const metaGuards = ({ - removed: [] - }); - const resolveContext = { vm }; - const { resolver } = this; - if (resolver && resolver.setup) { - resolver.setup(resolveContext); - } - // TODO: optimize initial compute (once) - const meta = this.target.addSource(metadata, resolveContext, true); - const onRemoved = (removeGuard) => metaGuards.removed.push(removeGuard); - const unmount = (ignoreGuards) => this.unmount(!!ignoreGuards, meta, metaGuards, vm); - if (vm) { - vue.onUnmounted(unmount); - } - return { - meta, - onRemoved, - unmount - }; - } - unmount(ignoreGuards, meta, metaGuards, vm) { - if (vm) { - const { $el } = vm.proxy; - // Wait for element to be removed from DOM - if ($el && $el.offsetParent) { - let observer = new MutationObserver((records) => { - for (const { removedNodes } of records) { - if (!removedNodes) { - continue; - } - removedNodes.forEach((el) => { - if (el === $el && observer) { - observer.disconnect(); - observer = undefined; - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - }); - } - }); - observer.observe($el.parentNode, { childList: true }); - return; - } - } - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - async reallyUnmount(ignoreGuards, meta, metaGuards) { - this.target.delSource(meta); - if (!ignoreGuards && metaGuards) { - await Promise.all(metaGuards.removed.map(removeGuard => removeGuard())); - } - } - render({ slots } = {}) { - const active = this.target.context.active; - // TODO: clean this method - const { isSSR } = this; - // cleanup ssr tags if not yet done - if (!isSSR && !this.ssrCleanedUp) { - this.ssrCleanedUp = true; - const cleanUpSSR = () => { - const ssrTags = document.querySelectorAll(`[${ssrAttribute}]`); - if (ssrTags && ssrTags.length) { - ssrTags.forEach(el => el.parentNode && el.parentNode.removeChild(el)); - } - }; - if (document.readyState === 'loading') { - // Listen for DOM loaded because tags in the body couldnt - // have loaded yet once the manager does it first render - // (preferable there should only be one meta render on hydration) - window.addEventListener('DOMContentLoaded', cleanUpSSR, { once: true }); - } - else { - cleanUpSSR(); - } - } - const teleports = {}; - for (const key in active) { - const config = this.config[key] || {}; - let renderedNodes = renderMeta({ isSSR, metainfo: active, slots }, key, active[key], config); - if (!renderedNodes) { - continue; - } - if (!isArray(renderedNodes)) { - renderedNodes = [renderedNodes]; - } - let defaultTo = key !== 'base' && active[key].to; - if (!defaultTo && 'to' in config) { - defaultTo = config.to; - } - if (!defaultTo && 'attributesFor' in config) { - defaultTo = key; - } - for (const { to, vnode } of renderedNodes) { - addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); - } - } - if (slots) { - for (const slotName in slots) { - const tagName = slotName === 'default' ? 'head' : slotName; - // Only teleport the contents of head/body slots - if (tagName !== 'head' && tagName !== 'body') { - continue; - } - const slot = slots[slotName]; - if (isFunction(slot)) { - addVnode(this.isSSR, teleports, tagName, slot({ metainfo: active })); - } - } - } - return Object.keys(teleports).map((to) => { - const teleport = teleports[to]; - return vue.h(vue.Teleport, { to }, teleport); - }); - } + if (vue.isProxy(source)) { + vue.watch(source, function (newSource, oldSource) { + applyDifference(metaProxy.meta, newSource, oldSource); + }); + source = source.value; + } + + var metaProxy = manager.addMeta(source, vm); + return metaProxy; +} +function useActiveMeta() { + return vue.inject(metaActiveKey); } -const defaultOptions = { - keyName: 'metaInfo' -}; -const createMixin = options => ({ - created() { - const instance = vue.getCurrentInstance(); - if (!instance?.type || !(options.keyName in instance.type)) { - return; - } - const metaInfo = instance.type[options.keyName]; - if (isFunction(metaInfo)) { - const computedMetaInfo = vue.computed(metaInfo.bind(this)); - useMeta(computedMetaInfo); - } - else { - useMeta(metaInfo); - } - } -}); -const install = (app, _options = {}) => { - const options = Object.assign({}, defaultOptions, _options); - app.mixin(createMixin(options)); +var MetainfoImpl = vue.defineComponent({ + name: 'Metainfo', + inheritAttrs: false, + setup: function setup(_, _ref) { + var slots = _ref.slots; + return function () { + var manager = getCurrentManager(); + + if (!manager) { + return; + } + + return manager.render({ + slots: slots + }); + }; + } +}); +var Metainfo = MetainfoImpl; + +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +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; } +var ssrAttribute = 'data-vm-ssr'; +function addVnode(isSSR, teleports, to, vnodes) { + var _teleports$to; + + var nodes = isArray(vnodes) ? vnodes : [vnodes]; + + if (!isSSR) { + // Comments shouldnt have any use on the client as they are not reactive anyway + nodes.forEach(function (vnode, idx) { + if (vnode.type === vue.Comment) { + nodes.splice(idx, 1); + } + }); // only add ssrAttribute's for real meta tags + } else if (!to.endsWith('Attrs')) { + nodes.forEach(function (vnode) { + if (!vnode.props) { + vnode.props = {}; + } + + vnode.props[ssrAttribute] = true; + }); + } + + if (!teleports[to]) { + teleports[to] = []; + } + + (_teleports$to = teleports[to]).push.apply(_teleports$to, _toConsumableArray__default(nodes)); +} +var createMetaManager = function createMetaManager() { + var isSSR = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var config = arguments.length > 1 ? arguments[1] : undefined; + var resolver = arguments.length > 2 ? arguments[2] : undefined; + return MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); +}; +var MetaManager = /*#__PURE__*/function () { + function MetaManager(isSSR, config, target, resolver) { + _classCallCheck__default(this, MetaManager); + + _defineProperty__default(this, "isSSR", false); + + _defineProperty__default(this, "config", void 0); + + _defineProperty__default(this, "target", void 0); + + _defineProperty__default(this, "resolver", void 0); + + _defineProperty__default(this, "ssrCleanedUp", false); + + this.isSSR = isSSR; + this.config = config; + this.target = target; + + if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { + this.resolver = resolver; + } + } + + _createClass__default(MetaManager, [{ + key: "install", + value: function install(app) { + app.component('Metainfo', Metainfo); + app.config.globalProperties.$metaManager = this; + app.provide(metaActiveKey, this.target.context.active); + } + }, { + key: "addMeta", + value: function addMeta(metadata, vm) { + var _this = this; + + if (!vm) { + vm = vue.getCurrentInstance() || undefined; + } + + var metaGuards = { + removed: [] + }; + var resolveContext = { + vm: vm + }; + var resolver = this.resolver; + + if (resolver && resolver.setup) { + resolver.setup(resolveContext); + } // TODO: optimize initial compute (once) + + + var meta = this.target.addSource(metadata, resolveContext, true); + + var onRemoved = function onRemoved(removeGuard) { + return metaGuards.removed.push(removeGuard); + }; + + var unmount = function unmount(ignoreGuards) { + return _this.unmount(!!ignoreGuards, meta, metaGuards, vm); + }; + + if (vm) { + vue.onUnmounted(unmount); + } + + return { + meta: meta, + onRemoved: onRemoved, + unmount: unmount + }; + } + }, { + key: "unmount", + value: function unmount(ignoreGuards, meta, metaGuards, vm) { + var _this2 = this; + + if (vm) { + var $el = vm.proxy.$el; // Wait for element to be removed from DOM + + if ($el && $el.offsetParent) { + var observer = new MutationObserver(function (records) { + var _iterator = _createForOfIteratorHelper(records), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var removedNodes = _step.value.removedNodes; + + if (!removedNodes) { + continue; + } + + removedNodes.forEach(function (el) { + if (el === $el && observer) { + observer.disconnect(); + observer = undefined; + + _this2.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }); + observer.observe($el.parentNode, { + childList: true + }); + return; + } + } + + this.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }, { + key: "reallyUnmount", + value: function () { + var _reallyUnmount = _asyncToGenerator__default( /*#__PURE__*/_regeneratorRuntime__default.mark(function _callee(ignoreGuards, meta, metaGuards) { + return _regeneratorRuntime__default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + this.target.delSource(meta); + + if (!(!ignoreGuards && metaGuards)) { + _context.next = 4; + break; + } + + _context.next = 4; + return Promise.all(metaGuards.removed.map(function (removeGuard) { + return removeGuard(); + })); + + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function reallyUnmount(_x, _x2, _x3) { + return _reallyUnmount.apply(this, arguments); + } + + return reallyUnmount; + }() + }, { + key: "render", + value: function render() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + slots = _ref.slots; + + var active = this.target.context.active; // TODO: clean this method + + var isSSR = this.isSSR; // cleanup ssr tags if not yet done + + if (!isSSR && !this.ssrCleanedUp) { + this.ssrCleanedUp = true; + + var cleanUpSSR = function cleanUpSSR() { + var ssrTags = document.querySelectorAll("[".concat(ssrAttribute, "]")); + + if (ssrTags && ssrTags.length) { + ssrTags.forEach(function (el) { + return el.parentNode && el.parentNode.removeChild(el); + }); + } + }; + + if (document.readyState === 'loading') { + // Listen for DOM loaded because tags in the body couldnt + // have loaded yet once the manager does it first render + // (preferable there should only be one meta render on hydration) + window.addEventListener('DOMContentLoaded', cleanUpSSR, { + once: true + }); + } else { + cleanUpSSR(); + } + } + + var teleports = {}; + + for (var key in active) { + var config = this.config[key] || {}; + var renderedNodes = renderMeta({ + isSSR: isSSR, + metainfo: active, + slots: slots + }, key, active[key], config); + + if (!renderedNodes) { + continue; + } + + if (!isArray(renderedNodes)) { + renderedNodes = [renderedNodes]; + } + + var defaultTo = key !== 'base' && active[key].to; + + if (!defaultTo && 'to' in config) { + defaultTo = config.to; + } + + if (!defaultTo && 'attributesFor' in config) { + defaultTo = key; + } + + var _iterator2 = _createForOfIteratorHelper(renderedNodes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _step2.value, + to = _step2$value.to, + vnode = _step2$value.vnode; + addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + if (slots) { + for (var slotName in slots) { + var tagName = slotName === 'default' ? 'head' : slotName; // Only teleport the contents of head/body slots + + if (tagName !== 'head' && tagName !== 'body') { + continue; + } + + var slot = slots[slotName]; + + if (isFunction(slot)) { + addVnode(this.isSSR, teleports, tagName, slot({ + metainfo: active + })); + } + } + } + + return Object.keys(teleports).map(function (to) { + var teleport = teleports[to]; + return vue.h(vue.Teleport, { + to: to + }, teleport); + }); + } + }]); + + return MetaManager; +}(); + +_defineProperty__default(MetaManager, "create", function (isSSR, config, resolver) { + var resolve = function resolve(options, contexts, active, key, pathSegments) { + if (isFunction(resolver)) { + return resolver(options, contexts, active, key, pathSegments); + } + + return resolver.resolve(options, contexts, active, key, pathSegments); + }; + + var active = vue.reactive({}); + var mergedObject = createMergedObject(resolve, active); // TODO: validate resolver + + var manager = new MetaManager(isSSR, config, mergedObject, resolver); + return manager; +}); + +var defaultOptions = { + keyName: 'metaInfo' +}; +var createMixin = function createMixin(options) { + return { + created: function created() { + var instance = vue.getCurrentInstance(); + + if (!(instance !== null && instance !== void 0 && instance.type) || !(options.keyName in instance.type)) { + return; + } + + var metaInfo = instance.type[options.keyName]; + + if (isFunction(metaInfo)) { + var computedMetaInfo = vue.computed(metaInfo.bind(this)); + useMeta(computedMetaInfo); + } else { + useMeta(metaInfo); + } + } + }; +}; +var install = function install(app) { + var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var options = Object.assign({}, defaultOptions, _options); + app.mixin(createMixin(options)); }; exports.createMetaManager = createMetaManager; diff --git a/dist/vue-meta.d.ts b/dist/vue-meta.d.ts index 55764b4d..9a70cc4a 100644 --- a/dist/vue-meta.d.ts +++ b/dist/vue-meta.d.ts @@ -46,7 +46,7 @@ declare type MergedObjectBuilder = { }; declare type CreateMetaManagerMethod = (isSSR: boolean, config: MetaConfig, resolver: MetaResolver | ResolveMethod) => MetaManager; -declare const createMetaManager: (isSSR?: boolean, config?: MetaConfig | undefined, resolver?: MetaResolver | undefined) => MetaManager; +declare const createMetaManager: (isSSR?: boolean, config?: MetaConfig, resolver?: MetaResolver) => MetaManager; declare class MetaManager { isSSR: boolean; config: MetaConfig; diff --git a/dist/vue-meta.esm-browser.js b/dist/vue-meta.esm-browser.js index 2b6210ff..bbec951a 100644 --- a/dist/vue-meta.esm-browser.js +++ b/dist/vue-meta.esm-browser.js @@ -6,42 +6,60 @@ * @license MIT */ +import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator'; +import _classCallCheck from '@babel/runtime/helpers/classCallCheck'; +import _createClass from '@babel/runtime/helpers/createClass'; +import _defineProperty from '@babel/runtime/helpers/defineProperty'; +import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; +import _regeneratorRuntime from '@babel/runtime/regenerator'; import { markRaw, h, getCurrentInstance, isProxy, watch, inject, defineComponent, reactive, onUnmounted, Teleport, Comment, computed } from 'vue'; +import _typeof from '@babel/runtime/helpers/typeof'; +import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; -const resolveOption = (predicament, initialValue) => (options, contexts) => { - let resolvedIndex = -1; - contexts.reduce((acc, context, index) => { - const retval = predicament(acc, context); - if (retval !== acc) { - resolvedIndex = index; - return retval; - } - return acc; - }, initialValue); - if (resolvedIndex > -1) { - return options[resolvedIndex]; - } +var resolveOption = function resolveOption(predicament, initialValue) { + return function (options, contexts) { + var resolvedIndex = -1; + contexts.reduce(function (acc, context, index) { + var retval = predicament(acc, context); + + if (retval !== acc) { + resolvedIndex = index; + return retval; + } + + return acc; + }, initialValue); + + if (resolvedIndex > -1) { + return options[resolvedIndex]; + } + }; }; -const setup = (context) => { - let depth = 0; - if (context.vm) { - let { vm } = context; - do { - if (vm.parent) { - depth++; - vm = vm.parent; - } - } while (vm && vm.parent && vm !== vm.root); - } - context.depth = depth; -}; -const resolve = resolveOption((currentValue, context) => { - const { depth } = context; - if (!currentValue || depth > currentValue) { - return depth; - } - return currentValue; +var setup = function setup(context) { + var depth = 0; + + if (context.vm) { + var vm = context.vm; + + do { + if (vm.parent) { + depth++; + vm = vm.parent; + } + } while (vm && vm.parent && vm !== vm.root); + } + + context.depth = depth; +}; +var resolve = resolveOption(function (currentValue, context) { + var depth = context.depth; + + if (!currentValue || depth > currentValue) { + return depth; + } + + return currentValue; }); var defaultResolver = /*#__PURE__*/Object.freeze({ @@ -50,105 +68,98 @@ var defaultResolver = /*#__PURE__*/Object.freeze({ resolve: resolve }); -const defaultConfig = { - body: { - tag: 'script', - to: 'body' - }, - base: { - valueAttribute: 'href' - }, - charset: { - tag: 'meta', - nameless: true, - valueAttribute: 'charset' - }, - description: { - tag: 'meta' - }, - og: { - group: true, - namespacedAttribute: true, - tag: 'meta', - keyAttribute: 'property' - }, - twitter: { - group: true, - namespacedAttribute: true, - tag: 'meta' - }, - htmlAttrs: { - attributesFor: 'html' - }, - headAttrs: { - attributesFor: 'head' - }, - bodyAttrs: { - attributesFor: 'body' - } +var defaultConfig = { + body: { + tag: 'script', + to: 'body' + }, + base: { + valueAttribute: 'href' + }, + charset: { + tag: 'meta', + nameless: true, + valueAttribute: 'charset' + }, + description: { + tag: 'meta' + }, + og: { + group: true, + namespacedAttribute: true, + tag: 'meta', + keyAttribute: 'property' + }, + twitter: { + group: true, + namespacedAttribute: true, + tag: 'meta' + }, + htmlAttrs: { + attributesFor: 'html' + }, + headAttrs: { + attributesFor: 'head' + }, + bodyAttrs: { + attributesFor: 'body' + } }; /* * This is a fixed config for real HTML tags - */ -const tags = { - title: { - attributes: false - }, - base: { - contentAsAttribute: true, - attributes: ['href', 'target'] - }, - meta: { - contentAsAttribute: true, - keyAttribute: 'name', - attributes: ['content', 'name', 'http-equiv', 'charset'] - }, - link: { - contentAsAttribute: true, - attributes: [ - 'href', - 'crossorigin', - 'rel', - 'media', - 'integrity', - 'hreflang', - 'type', - 'referrerpolicy', - 'sizes', - 'imagesrcset', - 'imagesizes', - 'as', - 'color' - ] - }, - style: { - attributes: ['media'] - }, - script: { - attributes: [ - 'src', - 'type', - 'nomodule', - 'async', - 'defer', - 'crossorigin', - 'integrity', - 'referrerpolicy' - ] - }, - noscript: { - attributes: false - } + */ +var tags = { + title: { + attributes: false + }, + base: { + contentAsAttribute: true, + attributes: ['href', 'target'] + }, + meta: { + contentAsAttribute: true, + keyAttribute: 'name', + attributes: ['content', 'name', 'http-equiv', 'charset'] + }, + link: { + contentAsAttribute: true, + attributes: ['href', 'crossorigin', 'rel', 'media', 'integrity', 'hreflang', 'type', 'referrerpolicy', 'sizes', 'imagesrcset', 'imagesizes', 'as', 'color'] + }, + style: { + attributes: ['media'] + }, + script: { + attributes: ['src', 'type', 'nomodule', 'async', 'defer', 'crossorigin', 'integrity', 'referrerpolicy'] + }, + noscript: { + attributes: false + } }; -function getTagConfigItem(tagOrName, key) { - for (const name of tagOrName) { - const tag = tags[name]; - if (name && tag) { - return tag[key]; - } - } +function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(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$5(o, minLen); } + +function _arrayLikeToArray$5(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 getTagConfigItem(tagOrName, key) { + var _iterator = _createForOfIteratorHelper$5(tagOrName), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var name = _step.value; + var tag = tags[name]; + + if (name && tag) { + return tag[key]; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } } /** @@ -158,6 +169,7 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ + Object.freeze({}) ; Object.freeze([]) ; @@ -169,805 +181,1275 @@ const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const isPlainObject = (val) => toTypeString(val) === '[object Object]'; -// https://github.com/microsoft/TypeScript/issues/1863 -const IS_PROXY = Symbol('kIsProxy'); -const PROXY_SOURCES = Symbol('kProxySources'); -const PROXY_TARGET = Symbol('kProxyTarget'); -const RESOLVE_CONTEXT = Symbol('kResolveContext'); - -// See: https://github.com/vuejs/vue-next/blob/08b4e8815da4e8911058ccbab986bea6365c3352/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts -function clone(v) { - if (isArray(v)) { - return v.map(clone); - } - if (isObject(v)) { - const res = {}; - for (const key in v) { - // never clone the context - if (key === 'context') { - res[key] = v[key]; - } - else { - res[key] = clone(v[key]); - } - } - return res; - } - return v; +// https://github.com/microsoft/TypeScript/issues/1863 +var IS_PROXY = Symbol('kIsProxy'); +var PROXY_SOURCES = Symbol('kProxySources'); +var PROXY_TARGET = Symbol('kProxyTarget'); +var RESOLVE_CONTEXT = Symbol('kResolveContext'); + +function clone(v) { + if (isArray(v)) { + return v.map(clone); + } + + if (isObject(v)) { + var res = {}; + + for (var key in v) { + // never clone the context + if (key === 'context') { + res[key] = v[key]; + } else { + res[key] = clone(v[key]); + } + } + + return res; + } + + return v; } -const pluck = (collection, key, callback) => { - const plucked = []; - for (const row of collection) { - if (row && key in row) { - plucked.push(row[key]); - if (callback) { - callback(row); - } - } - } - return plucked; +function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(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$4(o, minLen); } + +function _arrayLikeToArray$4(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; } + +var pluck = function pluck(collection, key, callback) { + var plucked = []; + + var _iterator = _createForOfIteratorHelper$4(collection), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var row = _step.value; + + if (row && key in row) { + plucked.push(row[key]); + + if (callback) { + callback(row); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return plucked; }; -const allKeys = (source, ...sources) => { - const keys = source ? Object.keys(source) : []; - if (sources) { - for (const source of sources) { - if (!source || !isObject(source)) { - continue; - } - for (const key in source) { - if (!keys.includes(key)) { - keys.push(key); - } - } - } - } - // TODO: add check for consistent types for each key (dev only) - return keys; -}; -const recompute = (context, path = [], target, sources) => { - const setTargetAndSources = !target && !sources; - if (setTargetAndSources) { - ({ active: target, sources } = context); - if (path.length) { - for (let i = 0; i < path.length; i++) { - const seg = path[i]; - if (!target || !target[seg]) { - { - // eslint-disable-next-line no-console - console.error(`recompute: segment ${seg} not found on target`, path, target); - } - return; - } - target = target[seg]; - sources = sources.map(source => source[seg]).filter(Boolean); - } - } - } - if (!target || !sources) { - return; - } - const keys = allKeys(...sources); - // Clean up properties that dont exists anymore - const targetKeys = Object.keys(target); - for (const key of targetKeys) { - if (!keys.includes(key)) { - delete target[key]; - } - } - for (const key of keys) { - // This assumes consistent types usages for keys across sources - // @ts-ignore - let isObject = false; - for (let i = 0; i < sources.length; i++) { - const source = sources[i]; - if (source && key in source && source[key] !== undefined) { - isObject = isPlainObject(source[key]); - break; - } - } - if (isObject) { - if (!target[key]) { - target[key] = {}; - } - const keySources = []; - for (const source of sources) { - if (key in source) { - // @ts-ignore - keySources.push(source[key]); - } - } - recompute(context, [...path, key], target[key], keySources); - continue; - } - // Ensure the target is an array if source is an array and target is empty - // @ts-ignore - if (!target[key] && isArray(sources[0][key])) { - target[key] = []; - } - const keyContexts = []; - const keySources = pluck(sources, key, source => keyContexts.push(source[RESOLVE_CONTEXT])); - let resolved = context.resolve(keySources, keyContexts, target[key], key, path); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - target[key] = resolved; - } +var debugFn = function debugFn(logFn) { + var setChildFns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fn = function fn() { + try { + throw new Error('DEBUG'); + } catch (err) { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logFn.apply(void 0, args.concat(['\n', err])); + } + }; + + if (setChildFns) { + fn.warn = debugFn(console.warn); // eslint-disable-line no-console + + fn.error = debugFn(console.error); // eslint-disable-line no-console + } + + return fn; }; +debugFn(console.log, true); // eslint-disable-line no-console -const createProxy = (context, target, resolveContext, pathSegments = []) => { - const handler = createHandler(context, resolveContext, pathSegments); - const proxy = markRaw(new Proxy(target, handler)); - if (!pathSegments.length && context.sources) { - context.sources.push(proxy); - } - return proxy; -}; -const createHandler = (context, resolveContext, pathSegments = []) => ({ - get: (target, key, receiver) => { - if (key === IS_PROXY) { - return true; - } - if (key === PROXY_SOURCES) { - return context.sources; - } - if (key === PROXY_TARGET) { - return target; - } - if (key === RESOLVE_CONTEXT) { - return resolveContext; - } - let value = Reflect.get(target, key, receiver); - if (!isObject(value)) { - return value; - } - // Also return a merge proxy for nested objects - if (!value[IS_PROXY]) { - const keyPath = [...pathSegments, key]; - value = createProxy(context, value, resolveContext, keyPath); - Reflect.set(target, key, value); - } - return value; - }, - set: (target, key, value) => { - const success = Reflect.set(target, key, value); - // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) - if (success) { - const isArrayItem = isArray(target); - let hasArrayParent = false; - let { sources: proxies, active } = context; - let activeSegmentKey; - let index = 0; - for (const segment of pathSegments) { - proxies = pluck(proxies, segment); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - if (isArray(active)) { - hasArrayParent = true; - } - active = active[segment]; - index++; - } - if (hasArrayParent) { - // TODO: fix that we dont have to recompute the full merged object - // we should only have to recompute the branch that has changed - // but there is an issue here with supporting both arrays of strings - // as collections (parent vs parent of parent we need to trigger the - // update from) - recompute(context); - return success; - } - else if (isPlainObject(value)) { - // if an object was assigned to this key make sure to recompute all - // of its individual properies - recompute(context, pathSegments); - return success; - } - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - // Ensure to clone if value is an object, cause sources is an array of - // the sourceProxies and not the sources so we could trigger an endless loop when - // updating a prop on an obj as the prop on the active object refers to - // a prop on a proxy - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) - return success; - }, - deleteProperty: (target, key) => { - const success = Reflect.deleteProperty(target, key); - // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) - if (success) { - const isArrayItem = isArray(target); - let activeSegmentKey; - let proxies = context.sources; - let active = context.active; - let index = 0; - for (const segment of pathSegments) { - // @ts-ignore - proxies = proxies.map(proxy => proxy && proxy[segment]); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - active = active[segment]; - index++; - } - // Check if the key still exists in one of the sourceProxies, - // if so resolve the new value, if not remove the key - if (proxies.some(proxy => proxy && (key in proxy))) { - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', resolved) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - else { - delete active[key]; - } - } - return success; - } -}); +function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(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$3(o, minLen); } + +function _arrayLikeToArray$3(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; } +var allKeys = function allKeys(source) { + var keys = source ? Object.keys(source) : []; + + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (sources) { + var _iterator = _createForOfIteratorHelper$3(sources), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _source = _step.value; + + if (!_source || !isObject(_source)) { + continue; + } + + for (var key in _source) { + if (!keys.includes(key)) { + keys.push(key); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } // TODO: add check for consistent types for each key (dev only) + + + return keys; +}; +var recompute = function recompute(context) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var target = arguments.length > 2 ? arguments[2] : undefined; + var sources = arguments.length > 3 ? arguments[3] : undefined; + var setTargetAndSources = !target && !sources; + + if (setTargetAndSources) { + target = context.active; + sources = context.sources; + + if (path.length) { + var _loop = function _loop(i) { + var seg = path[i]; + + if (!target || !target[seg]) { + { + // eslint-disable-next-line no-console + console.error("recompute: segment ".concat(seg, " not found on target"), path, target); + } + + return { + v: void 0 + }; + } + + target = target[seg]; + sources = sources.map(function (source) { + return source[seg]; + }).filter(Boolean); + }; + + for (var i = 0; i < path.length; i++) { + var _ret = _loop(i); + + if (_typeof(_ret) === "object") return _ret.v; + } + } + } + + if (!target || !sources) { + return; + } + + var keys = allKeys.apply(void 0, _toConsumableArray(sources)); // Clean up properties that dont exists anymore + + var targetKeys = Object.keys(target); + + for (var _i = 0, _targetKeys = targetKeys; _i < _targetKeys.length; _i++) { + var key = _targetKeys[_i]; + + if (!keys.includes(key)) { + delete target[key]; + } + } + + var _iterator2 = _createForOfIteratorHelper$3(keys), + _step2; + + try { + var _loop2 = function _loop2() { + var key = _step2.value; + // This assumes consistent types usages for keys across sources + // @ts-ignore + var isObject = false; + + for (var _i2 = 0; _i2 < sources.length; _i2++) { + var source = sources[_i2]; + + if (source && key in source && source[key] !== undefined) { + isObject = isPlainObject(source[key]); + break; + } + } + + if (isObject) { + if (!target[key]) { + target[key] = {}; + } + + var _keySources = []; + + var _iterator3 = _createForOfIteratorHelper$3(sources), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _source2 = _step3.value; + + if (key in _source2) { + // @ts-ignore + _keySources.push(_source2[key]); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + recompute(context, [].concat(_toConsumableArray(path), [key]), target[key], _keySources); + return "continue"; + } // Ensure the target is an array if source is an array and target is empty + // @ts-ignore + + + if (!target[key] && isArray(sources[0][key])) { + target[key] = []; + } + + var keyContexts = []; + var keySources = pluck(sources, key, function (source) { + return keyContexts.push(source[RESOLVE_CONTEXT]); + }); + var resolved = context.resolve(keySources, keyContexts, target[key], key, path); -const createMergedObject = (resolve, active) => { - const sources = []; - const context = { - active, - resolve, - sources - }; - const compute = () => recompute(context); - return { - context, - compute, - addSource: (source, resolveContext, recompute = false) => { - const proxy = createProxy(context, source, resolveContext || {}); - if (recompute) { - compute(); - } - return proxy; - }, - delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); - if (index > -1) { - sources.splice(index, 1); - if (recompute) { - compute(); - } - return true; - } - return false; - } - }; + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } + + target[key] = resolved; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret2 = _loop2(); + + if (_ret2 === "continue") continue; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } +}; + +function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(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$2(o, minLen); } + +function _arrayLikeToArray$2(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; } +var createProxy = function createProxy(context, target, resolveContext) { + var pathSegments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + var handler = createHandler(context, resolveContext, pathSegments); + var proxy = markRaw(new Proxy(target, handler)); + + if (!pathSegments.length && context.sources) { + context.sources.push(proxy); + } + + return proxy; +}; +var createHandler = function createHandler(context, resolveContext) { + var pathSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + return { + get: function get(target, key, receiver) { + if (key === IS_PROXY) { + return true; + } + + if (key === PROXY_SOURCES) { + return context.sources; + } + + if (key === PROXY_TARGET) { + return target; + } + + if (key === RESOLVE_CONTEXT) { + return resolveContext; + } + + var value = Reflect.get(target, key, receiver); + + if (!isObject(value)) { + return value; + } // Also return a merge proxy for nested objects + + + if (!value[IS_PROXY]) { + var keyPath = [].concat(_toConsumableArray(pathSegments), [key]); + value = createProxy(context, value, resolveContext, keyPath); + Reflect.set(target, key, value); + } + + return value; + }, + set: function set(target, key, value) { + var success = Reflect.set(target, key, value); // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) + + if (success) { + var isArrayItem = isArray(target); + var hasArrayParent = false; + var proxies = context.sources, + active = context.active; + var activeSegmentKey; + var index = 0; + + var _iterator = _createForOfIteratorHelper$2(pathSegments), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var segment = _step.value; + proxies = pluck(proxies, segment); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + break; + } + + if (isArray(active)) { + hasArrayParent = true; + } + + active = active[segment]; + index++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + if (hasArrayParent) { + // TODO: fix that we dont have to recompute the full merged object + // we should only have to recompute the branch that has changed + // but there is an issue here with supporting both arrays of strings + // as collections (parent vs parent of parent we need to trigger the + // update from) + recompute(context); + return success; + } else if (isPlainObject(value)) { + // if an object was assigned to this key make sure to recompute all + // of its individual properies + recompute(context, pathSegments); + return success; + } + + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); // Ensure to clone if value is an object, cause sources is an array of + // the sourceProxies and not the sources so we could trigger an endless loop when + // updating a prop on an obj as the prop on the active object refers to + // a prop on a proxy + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) + + + return success; + }, + deleteProperty: function deleteProperty(target, key) { + var success = Reflect.deleteProperty(target, key); // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) + + if (success) { + var isArrayItem = isArray(target); + var activeSegmentKey; + var proxies = context.sources; + var active = context.active; + var index = 0; + + var _iterator2 = _createForOfIteratorHelper$2(pathSegments), + _step2; + + try { + var _loop = function _loop() { + var segment = _step2.value; + // @ts-ignore + proxies = proxies.map(function (proxy) { + return proxy && proxy[segment]; + }); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + return "break"; + } + + active = active[segment]; + index++; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret = _loop(); + + if (_ret === "break") break; + } // Check if the key still exists in one of the sourceProxies, + // if so resolve the new value, if not remove the key + + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + if (proxies.some(function (proxy) { + return proxy && key in proxy; + })) { + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', resolved) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } else { + delete active[key]; + } + } + + return success; + } + }; }; -const cachedElements = {}; -function renderMeta(context, key, data, config) { - // console.info('renderMeta', key, data, config) - if ('attributesFor' in config) { - return renderAttributes(context, key, data, config); - } - if ('group' in config) { - return renderGroup(context, key, data, config); - } - return renderTag(context, key, data, config); -} -function renderGroup(context, key, data, config) { - // console.info('renderGroup', key, data, config) - if (isArray(data)) { - { - // eslint-disable-next-line no-console - console.warn('Specifying an array for group properties isnt supported'); - } - // config.attributes = getConfigKey([key, config.tag], 'attributes', config) - return []; - } - return Object.keys(data) - .map((childKey) => { - const groupConfig = { - group: key, - data - }; - if (config.namespaced) { - groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; - } - else if (config.namespacedAttribute) { - const namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; - groupConfig.fullName = `${namespace}:${childKey}`; - groupConfig.slotName = `${namespace}(${childKey})`; - } - return renderTag(context, key, data[childKey], config, groupConfig); - }) - .filter(Boolean) - .flat(); -} -function renderTag(context, key, data, config = {}, groupConfig) { - // console.info('renderTag', key, data, config, groupConfig) - const contentAttributes = ['content', 'json', 'rawContent']; - const getTagConfig = (key) => getTagConfigItem([tag, config.tag], key); - if (isArray(data)) { - return data - .map((child) => { - return renderTag(context, key, child, config, groupConfig); - }) - .filter(Boolean) - .flat(); - } - const { tag = config.tag || key } = data; - let content = ''; - let hasChilds = false; - let isRaw = false; - if (isString(data)) { - content = data; - } - else if (data.children && isArray(data.children)) { - hasChilds = true; - content = data.children.map((child) => { - const data = renderTag(context, key, child, config, groupConfig); - if (isArray(data)) { - return data.map(({ vnode }) => vnode); - } - return data && data.vnode; - }); - } - else { - let i = 0; - for (const contentAttribute of contentAttributes) { - if (!content && data[contentAttribute]) { - if (i === 1) { - content = JSON.stringify(data[contentAttribute]); - } - else { - content = data[contentAttribute]; - } - isRaw = i > 1; - break; - } - i++; - } - } - const fullName = (groupConfig && groupConfig.fullName) || key; - const slotName = (groupConfig && groupConfig.slotName) || key; - let { attrs: attributes } = data; - if (!attributes && typeof data === 'object') { - attributes = { ...data }; - delete attributes.tag; - delete attributes.children; - delete attributes.to; - // cleanup all content attributes - for (const attr of contentAttributes) { - delete attributes[attr]; - } - } - else if (!attributes) { - attributes = {}; - } - if (hasChilds) { - content = getSlotContent(context, slotName, content, data); - } - else { - const contentAsAttribute = !!getTagConfig('contentAsAttribute'); - let { valueAttribute } = config; - if (!valueAttribute && contentAsAttribute) { - const [tagAttribute] = getTagConfig('attributes'); - valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; - } - if (!valueAttribute) { - content = getSlotContent(context, slotName, content, data); - } - else { - const { nameless } = config; - if (!nameless) { - const keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); - if (keyAttribute) { - attributes[keyAttribute] = fullName; - } - } - attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); - content = ''; - } - } - const finalTag = groupConfig && groupConfig.tagNamespace - ? `${groupConfig.tagNamespace}:${tag}` - : tag; - if (finalTag === 'title' && !context.isSSR) { - document.title = content; - return; - } - // console.info('FINAL TAG', finalTag) - // console.log(' ATTRIBUTES', attributes) - // console.log(' CONTENT', content) - // console.log(data, attributes, config) - if (isRaw && content) { - attributes.innerHTML = content; - } - // Ignore empty string content - const vnode = h(finalTag, attributes, content || undefined); - return { - to: data.to, - vnode - }; -} -function renderAttributes(context, key, data, config) { - // console.info('renderAttributes', key, data, config) - const { attributesFor } = config; - if (!attributesFor || !data) { - return; - } - if (context.isSSR) { - // render attributes in a placeholder vnode so Vue - // will render the string for us - return { - to: '', - vnode: h(`ssr-${attributesFor}`, data) - }; - } - if (!cachedElements[attributesFor]) { - const [el, el2] = Array.from(document.querySelectorAll(attributesFor)); - if (!el) { - // eslint-disable-next-line no-console - console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); - return; - } - if (el2) { - // eslint-disable-next-line no-console - console.warn('Found multiple elements for selector', attributesFor); - } - cachedElements[attributesFor] = { - el, - attrs: [] - }; - } - const { el, attrs } = cachedElements[attributesFor]; - for (const attr in data) { - let content = getSlotContent(context, `${key}(${attr})`, data[attr], data); - if (isArray(content)) { - content = content.join(','); - } - el.setAttribute(attr, content || ''); - if (!attrs.includes(attr)) { - attrs.push(attr); - } - } - const attrsToRemove = attrs.filter(attr => !data[attr]); - for (const attr of attrsToRemove) { - el.removeAttribute(attr); - } -} -function getSlotContent({ metainfo, slots }, slotName, content, groupConfig) { - const slot = slots && slots[slotName]; - if (!slot || !isFunction(slot)) { - return content; - } - const slotScopeProps = { - content, - metainfo - }; - if (groupConfig && groupConfig.group) { - const { group, data } = groupConfig; - slotScopeProps[group] = data; - } - const slotContent = slot(slotScopeProps); - if (slotContent && slotContent.length) { - const { children } = slotContent[0]; - return children ? children.toString() : ''; - } - return content; +var createMergedObject = function createMergedObject(resolve, active) { + var sources = []; + var context = { + active: active, + resolve: resolve, + sources: sources + }; + + var compute = function compute() { + return recompute(context); + }; + + return { + context: context, + compute: compute, + addSource: function addSource(source, resolveContext) { + var recompute = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var proxy = createProxy(context, source, resolveContext || {}); + + if (recompute) { + compute(); + } + + return proxy; + }, + delSource: function delSource(sourceOrProxy) { + var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var index = sources.findIndex(function (source) { + return source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy; + }); + + if (index > -1) { + sources.splice(index, 1); + + if (recompute) { + compute(); + } + + return true; + } + + return false; + } + }; +}; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(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$1(o, minLen); } + +function _arrayLikeToArray$1(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; } +var cachedElements = {}; +function renderMeta(context, key, data, config) { + // console.info('renderMeta', key, data, config) + if ('attributesFor' in config) { + return renderAttributes(context, key, data, config); + } + + if ('group' in config) { + return renderGroup(context, key, data, config); + } + + return renderTag(context, key, data, config); +} +function renderGroup(context, key, data, config) { + // console.info('renderGroup', key, data, config) + if (isArray(data)) { + { + // eslint-disable-next-line no-console + console.warn('Specifying an array for group properties isnt supported'); + } // config.attributes = getConfigKey([key, config.tag], 'attributes', config) + + + return []; + } + + return Object.keys(data).map(function (childKey) { + var groupConfig = { + group: key, + data: data + }; + + if (config.namespaced) { + groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; + } else if (config.namespacedAttribute) { + var namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; + groupConfig.fullName = "".concat(namespace, ":").concat(childKey); + groupConfig.slotName = "".concat(namespace, "(").concat(childKey, ")"); + } + + return renderTag(context, key, data[childKey], config, groupConfig); + }).filter(Boolean).flat(); } +function renderTag(context, key, data) { + var config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var groupConfig = arguments.length > 4 ? arguments[4] : undefined; + // console.info('renderTag', key, data, config, groupConfig) + var contentAttributes = ['content', 'json', 'rawContent']; -const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; -const PolySymbol = (name) => -// vm = vue meta -hasSymbol - ? Symbol('[vue-meta]: ' + name ) - : ('[vue-meta]: ' ) + name; -const metaActiveKey = /*#__PURE__*/ PolySymbol('meta_active' ); + var getTagConfig = function getTagConfig(key) { + return getTagConfigItem([tag, config.tag], key); + }; + + if (isArray(data)) { + return data.map(function (child) { + return renderTag(context, key, child, config, groupConfig); + }).filter(Boolean).flat(); + } + + var _data$tag = data.tag, + tag = _data$tag === void 0 ? config.tag || key : _data$tag; + var content = ''; + var hasChilds = false; + var isRaw = false; + + if (isString(data)) { + content = data; + } else if (data.children && isArray(data.children)) { + hasChilds = true; + content = data.children.map(function (child) { + var data = renderTag(context, key, child, config, groupConfig); + + if (isArray(data)) { + return data.map(function (_ref) { + var vnode = _ref.vnode; + return vnode; + }); + } + + return data && data.vnode; + }); + } else { + var i = 0; + + var _iterator = _createForOfIteratorHelper$1(contentAttributes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var contentAttribute = _step.value; + + if (!content && data[contentAttribute]) { + if (i === 1) { + content = JSON.stringify(data[contentAttribute]); + } else { + content = data[contentAttribute]; + } + + isRaw = i > 1; + break; + } + + i++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + var fullName = groupConfig && groupConfig.fullName || key; + var slotName = groupConfig && groupConfig.slotName || key; + var attributes = data.attrs; + + if (!attributes && _typeof(data) === 'object') { + attributes = _objectSpread({}, data); + delete attributes.tag; + delete attributes.children; + delete attributes.to; // cleanup all content attributes + + var _iterator2 = _createForOfIteratorHelper$1(contentAttributes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var attr = _step2.value; + delete attributes[attr]; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } else if (!attributes) { + attributes = {}; + } + + if (hasChilds) { + content = getSlotContent(context, slotName, content, data); + } else { + var contentAsAttribute = !!getTagConfig('contentAsAttribute'); + var valueAttribute = config.valueAttribute; + + if (!valueAttribute && contentAsAttribute) { + var _getTagConfig = getTagConfig('attributes'), + _getTagConfig2 = _slicedToArray(_getTagConfig, 1), + tagAttribute = _getTagConfig2[0]; + + valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; + } + + if (!valueAttribute) { + content = getSlotContent(context, slotName, content, data); + } else { + var nameless = config.nameless; + + if (!nameless) { + var keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); + + if (keyAttribute) { + attributes[keyAttribute] = fullName; + } + } + + attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); + content = ''; + } + } + + var finalTag = groupConfig && groupConfig.tagNamespace ? "".concat(groupConfig.tagNamespace, ":").concat(tag) : tag; + + if (finalTag === 'title' && !context.isSSR) { + document.title = content; + return; + } // console.info('FINAL TAG', finalTag) + // console.log(' ATTRIBUTES', attributes) + // console.log(' CONTENT', content) + // console.log(data, attributes, config) + + + if (isRaw && content) { + attributes.innerHTML = content; + } // Ignore empty string content + + + var vnode = h(finalTag, attributes, content || undefined); + return { + to: data.to, + vnode: vnode + }; +} +function renderAttributes(context, key, data, config) { + // console.info('renderAttributes', key, data, config) + var attributesFor = config.attributesFor; + + if (!attributesFor || !data) { + return; + } + + if (context.isSSR) { + // render attributes in a placeholder vnode so Vue + // will render the string for us + return { + to: '', + vnode: h("ssr-".concat(attributesFor), data) + }; + } + + if (!cachedElements[attributesFor]) { + var _Array$from = Array.from(document.querySelectorAll(attributesFor)), + _Array$from2 = _slicedToArray(_Array$from, 2), + _el = _Array$from2[0], + el2 = _Array$from2[1]; + + if (!_el) { + // eslint-disable-next-line no-console + console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); + return; + } + + if (el2) { + // eslint-disable-next-line no-console + console.warn('Found multiple elements for selector', attributesFor); + } + + cachedElements[attributesFor] = { + el: _el, + attrs: [] + }; + } + + var _cachedElements$attri = cachedElements[attributesFor], + el = _cachedElements$attri.el, + attrs = _cachedElements$attri.attrs; + + for (var attr in data) { + var content = getSlotContent(context, "".concat(key, "(").concat(attr, ")"), data[attr], data); + + if (isArray(content)) { + content = content.join(','); + } + + el.setAttribute(attr, content || ''); + + if (!attrs.includes(attr)) { + attrs.push(attr); + } + } + + var attrsToRemove = attrs.filter(function (attr) { + return !data[attr]; + }); + + var _iterator3 = _createForOfIteratorHelper$1(attrsToRemove), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _attr = _step3.value; + el.removeAttribute(_attr); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } +} +function getSlotContent(_ref2, slotName, content, groupConfig) { + var metainfo = _ref2.metainfo, + slots = _ref2.slots; + var slot = slots && slots[slotName]; + + if (!slot || !isFunction(slot)) { + return content; + } + + var slotScopeProps = { + content: content, + metainfo: metainfo + }; + + if (groupConfig && groupConfig.group) { + var group = groupConfig.group, + data = groupConfig.data; + slotScopeProps[group] = data; + } + + var slotContent = slot(slotScopeProps); + + if (slotContent && slotContent.length) { + var children = slotContent[0].children; + return children ? children.toString() : ''; + } + + return content; +} + +var hasSymbol = typeof Symbol === 'function' && _typeof(Symbol.toStringTag) === 'symbol'; +var PolySymbol = function PolySymbol(name) { + return (// vm = vue meta + hasSymbol ? Symbol('[vue-meta]: ' + name ) : ('[vue-meta]: ' ) + name + ); +}; +var metaActiveKey = /*#__PURE__*/PolySymbol('meta_active' ); /** * Apply the differences between newSource & oldSource to target - */ -function applyDifference(target, newSource, oldSource) { - for (const key in newSource) { - if (!(key in oldSource)) { - target[key] = newSource[key]; - continue; - } - if (isObject(target[key])) { - applyDifference(target[key], newSource[key], oldSource[key]); - continue; - } - if (newSource[key] !== oldSource[key]) { - target[key] = newSource[key]; - } - } - for (const key in oldSource) { - if (!newSource || !(key in newSource)) { - delete target[key]; - } - } + */ + +function applyDifference(target, newSource, oldSource) { + for (var key in newSource) { + if (!(key in oldSource)) { + target[key] = newSource[key]; + continue; + } + + if (isObject(target[key])) { + applyDifference(target[key], newSource[key], oldSource[key]); + continue; + } + + if (newSource[key] !== oldSource[key]) { + target[key] = newSource[key]; + } + } + + for (var _key in oldSource) { + if (!newSource || !(_key in newSource)) { + delete target[_key]; + } + } } -function getCurrentManager(vm) { - if (!vm) { - vm = getCurrentInstance() || undefined; - } - if (!vm) { - return undefined; - } - return vm.appContext.config.globalProperties.$metaManager; -} -function useMeta(source, manager) { - const vm = getCurrentInstance() || undefined; - if (!manager && vm) { - manager = getCurrentManager(vm); - } - if (!manager) { - throw new Error('No manager or current instance'); - } - if (isProxy(source)) { - watch(source, (newSource, oldSource) => { - applyDifference(metaProxy.meta, newSource, oldSource); - }); - source = source.value; - } - const metaProxy = manager.addMeta(source, vm); - return metaProxy; -} -function useActiveMeta() { - return inject(metaActiveKey); +function getCurrentManager(vm) { + if (!vm) { + vm = getCurrentInstance() || undefined; + } + + if (!vm) { + return undefined; + } + + return vm.appContext.config.globalProperties.$metaManager; } +function useMeta(source, manager) { + var vm = getCurrentInstance() || undefined; + + if (!manager && vm) { + manager = getCurrentManager(vm); + } + + if (!manager) { + throw new Error('No manager or current instance'); + } -const MetainfoImpl = defineComponent({ - name: 'Metainfo', - inheritAttrs: false, - setup(_, { slots }) { - return () => { - const manager = getCurrentManager(); - if (!manager) { - return; - } - return manager.render({ slots }); - }; - } -}); -const Metainfo = MetainfoImpl; - -const ssrAttribute = 'data-vm-ssr'; -function addVnode(isSSR, teleports, to, vnodes) { - const nodes = (isArray(vnodes) ? vnodes : [vnodes]); - if (!isSSR) { - // Comments shouldnt have any use on the client as they are not reactive anyway - nodes.forEach((vnode, idx) => { - if (vnode.type === Comment) { - nodes.splice(idx, 1); - } - }); - // only add ssrAttribute's for real meta tags - } - else if (!to.endsWith('Attrs')) { - nodes.forEach((vnode) => { - if (!vnode.props) { - vnode.props = {}; - } - vnode.props[ssrAttribute] = true; - }); - } - if (!teleports[to]) { - teleports[to] = []; - } - teleports[to].push(...nodes); -} -const createMetaManager = (isSSR = false, config, resolver) => MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); -class MetaManager { - isSSR = false; - config; - target; - resolver; - ssrCleanedUp = false; - constructor(isSSR, config, target, resolver) { - this.isSSR = isSSR; - this.config = config; - this.target = target; - if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { - this.resolver = resolver; - } - } - static create = (isSSR, config, resolver) => { - const resolve = (options, contexts, active, key, pathSegments) => { - if (isFunction(resolver)) { - return resolver(options, contexts, active, key, pathSegments); - } - return resolver.resolve(options, contexts, active, key, pathSegments); - }; - const active = reactive({}); - const mergedObject = createMergedObject(resolve, active); - // TODO: validate resolver - const manager = new MetaManager(isSSR, config, mergedObject, resolver); - return manager; - }; - install(app) { - app.component('Metainfo', Metainfo); - app.config.globalProperties.$metaManager = this; - app.provide(metaActiveKey, this.target.context.active); - } - addMeta(metadata, vm) { - if (!vm) { - vm = getCurrentInstance() || undefined; - } - const metaGuards = ({ - removed: [] - }); - const resolveContext = { vm }; - const { resolver } = this; - if (resolver && resolver.setup) { - resolver.setup(resolveContext); - } - // TODO: optimize initial compute (once) - const meta = this.target.addSource(metadata, resolveContext, true); - const onRemoved = (removeGuard) => metaGuards.removed.push(removeGuard); - const unmount = (ignoreGuards) => this.unmount(!!ignoreGuards, meta, metaGuards, vm); - if (vm) { - onUnmounted(unmount); - } - return { - meta, - onRemoved, - unmount - }; - } - unmount(ignoreGuards, meta, metaGuards, vm) { - if (vm) { - const { $el } = vm.proxy; - // Wait for element to be removed from DOM - if ($el && $el.offsetParent) { - let observer = new MutationObserver((records) => { - for (const { removedNodes } of records) { - if (!removedNodes) { - continue; - } - removedNodes.forEach((el) => { - if (el === $el && observer) { - observer.disconnect(); - observer = undefined; - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - }); - } - }); - observer.observe($el.parentNode, { childList: true }); - return; - } - } - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - async reallyUnmount(ignoreGuards, meta, metaGuards) { - this.target.delSource(meta); - if (!ignoreGuards && metaGuards) { - await Promise.all(metaGuards.removed.map(removeGuard => removeGuard())); - } - } - render({ slots } = {}) { - const active = this.target.context.active; - // TODO: clean this method - const { isSSR } = this; - // cleanup ssr tags if not yet done - if (!isSSR && !this.ssrCleanedUp) { - this.ssrCleanedUp = true; - const cleanUpSSR = () => { - const ssrTags = document.querySelectorAll(`[${ssrAttribute}]`); - if (ssrTags && ssrTags.length) { - ssrTags.forEach(el => el.parentNode && el.parentNode.removeChild(el)); - } - }; - if (document.readyState === 'loading') { - // Listen for DOM loaded because tags in the body couldnt - // have loaded yet once the manager does it first render - // (preferable there should only be one meta render on hydration) - window.addEventListener('DOMContentLoaded', cleanUpSSR, { once: true }); - } - else { - cleanUpSSR(); - } - } - const teleports = {}; - for (const key in active) { - const config = this.config[key] || {}; - let renderedNodes = renderMeta({ isSSR, metainfo: active, slots }, key, active[key], config); - if (!renderedNodes) { - continue; - } - if (!isArray(renderedNodes)) { - renderedNodes = [renderedNodes]; - } - let defaultTo = key !== 'base' && active[key].to; - if (!defaultTo && 'to' in config) { - defaultTo = config.to; - } - if (!defaultTo && 'attributesFor' in config) { - defaultTo = key; - } - for (const { to, vnode } of renderedNodes) { - addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); - } - } - if (slots) { - for (const slotName in slots) { - const tagName = slotName === 'default' ? 'head' : slotName; - // Only teleport the contents of head/body slots - if (tagName !== 'head' && tagName !== 'body') { - continue; - } - const slot = slots[slotName]; - if (isFunction(slot)) { - addVnode(this.isSSR, teleports, tagName, slot({ metainfo: active })); - } - } - } - return Object.keys(teleports).map((to) => { - const teleport = teleports[to]; - return h(Teleport, { to }, teleport); - }); - } + if (isProxy(source)) { + watch(source, function (newSource, oldSource) { + applyDifference(metaProxy.meta, newSource, oldSource); + }); + source = source.value; + } + + var metaProxy = manager.addMeta(source, vm); + return metaProxy; +} +function useActiveMeta() { + return inject(metaActiveKey); } -const defaultOptions = { - keyName: 'metaInfo' -}; -const createMixin = options => ({ - created() { - const instance = getCurrentInstance(); - if (!instance?.type || !(options.keyName in instance.type)) { - return; - } - const metaInfo = instance.type[options.keyName]; - if (isFunction(metaInfo)) { - const computedMetaInfo = computed(metaInfo.bind(this)); - useMeta(computedMetaInfo); - } - else { - useMeta(metaInfo); - } - } -}); -const install = (app, _options = {}) => { - const options = Object.assign({}, defaultOptions, _options); - app.mixin(createMixin(options)); +var MetainfoImpl = defineComponent({ + name: 'Metainfo', + inheritAttrs: false, + setup: function setup(_, _ref) { + var slots = _ref.slots; + return function () { + var manager = getCurrentManager(); + + if (!manager) { + return; + } + + return manager.render({ + slots: slots + }); + }; + } +}); +var Metainfo = MetainfoImpl; + +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +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; } +var ssrAttribute = 'data-vm-ssr'; +function addVnode(isSSR, teleports, to, vnodes) { + var _teleports$to; + + var nodes = isArray(vnodes) ? vnodes : [vnodes]; + + if (!isSSR) { + // Comments shouldnt have any use on the client as they are not reactive anyway + nodes.forEach(function (vnode, idx) { + if (vnode.type === Comment) { + nodes.splice(idx, 1); + } + }); // only add ssrAttribute's for real meta tags + } else if (!to.endsWith('Attrs')) { + nodes.forEach(function (vnode) { + if (!vnode.props) { + vnode.props = {}; + } + + vnode.props[ssrAttribute] = true; + }); + } + + if (!teleports[to]) { + teleports[to] = []; + } + + (_teleports$to = teleports[to]).push.apply(_teleports$to, _toConsumableArray(nodes)); +} +var createMetaManager = function createMetaManager() { + var isSSR = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var config = arguments.length > 1 ? arguments[1] : undefined; + var resolver = arguments.length > 2 ? arguments[2] : undefined; + return MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); +}; +var MetaManager = /*#__PURE__*/function () { + function MetaManager(isSSR, config, target, resolver) { + _classCallCheck(this, MetaManager); + + _defineProperty(this, "isSSR", false); + + _defineProperty(this, "config", void 0); + + _defineProperty(this, "target", void 0); + + _defineProperty(this, "resolver", void 0); + + _defineProperty(this, "ssrCleanedUp", false); + + this.isSSR = isSSR; + this.config = config; + this.target = target; + + if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { + this.resolver = resolver; + } + } + + _createClass(MetaManager, [{ + key: "install", + value: function install(app) { + app.component('Metainfo', Metainfo); + app.config.globalProperties.$metaManager = this; + app.provide(metaActiveKey, this.target.context.active); + } + }, { + key: "addMeta", + value: function addMeta(metadata, vm) { + var _this = this; + + if (!vm) { + vm = getCurrentInstance() || undefined; + } + + var metaGuards = { + removed: [] + }; + var resolveContext = { + vm: vm + }; + var resolver = this.resolver; + + if (resolver && resolver.setup) { + resolver.setup(resolveContext); + } // TODO: optimize initial compute (once) + + + var meta = this.target.addSource(metadata, resolveContext, true); + + var onRemoved = function onRemoved(removeGuard) { + return metaGuards.removed.push(removeGuard); + }; + + var unmount = function unmount(ignoreGuards) { + return _this.unmount(!!ignoreGuards, meta, metaGuards, vm); + }; + + if (vm) { + onUnmounted(unmount); + } + + return { + meta: meta, + onRemoved: onRemoved, + unmount: unmount + }; + } + }, { + key: "unmount", + value: function unmount(ignoreGuards, meta, metaGuards, vm) { + var _this2 = this; + + if (vm) { + var $el = vm.proxy.$el; // Wait for element to be removed from DOM + + if ($el && $el.offsetParent) { + var observer = new MutationObserver(function (records) { + var _iterator = _createForOfIteratorHelper(records), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var removedNodes = _step.value.removedNodes; + + if (!removedNodes) { + continue; + } + + removedNodes.forEach(function (el) { + if (el === $el && observer) { + observer.disconnect(); + observer = undefined; + + _this2.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }); + observer.observe($el.parentNode, { + childList: true + }); + return; + } + } + + this.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }, { + key: "reallyUnmount", + value: function () { + var _reallyUnmount = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ignoreGuards, meta, metaGuards) { + return _regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + this.target.delSource(meta); + + if (!(!ignoreGuards && metaGuards)) { + _context.next = 4; + break; + } + + _context.next = 4; + return Promise.all(metaGuards.removed.map(function (removeGuard) { + return removeGuard(); + })); + + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function reallyUnmount(_x, _x2, _x3) { + return _reallyUnmount.apply(this, arguments); + } + + return reallyUnmount; + }() + }, { + key: "render", + value: function render() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + slots = _ref.slots; + + var active = this.target.context.active; // TODO: clean this method + + var isSSR = this.isSSR; // cleanup ssr tags if not yet done + + if (!isSSR && !this.ssrCleanedUp) { + this.ssrCleanedUp = true; + + var cleanUpSSR = function cleanUpSSR() { + var ssrTags = document.querySelectorAll("[".concat(ssrAttribute, "]")); + + if (ssrTags && ssrTags.length) { + ssrTags.forEach(function (el) { + return el.parentNode && el.parentNode.removeChild(el); + }); + } + }; + + if (document.readyState === 'loading') { + // Listen for DOM loaded because tags in the body couldnt + // have loaded yet once the manager does it first render + // (preferable there should only be one meta render on hydration) + window.addEventListener('DOMContentLoaded', cleanUpSSR, { + once: true + }); + } else { + cleanUpSSR(); + } + } + + var teleports = {}; + + for (var key in active) { + var config = this.config[key] || {}; + var renderedNodes = renderMeta({ + isSSR: isSSR, + metainfo: active, + slots: slots + }, key, active[key], config); + + if (!renderedNodes) { + continue; + } + + if (!isArray(renderedNodes)) { + renderedNodes = [renderedNodes]; + } + + var defaultTo = key !== 'base' && active[key].to; + + if (!defaultTo && 'to' in config) { + defaultTo = config.to; + } + + if (!defaultTo && 'attributesFor' in config) { + defaultTo = key; + } + + var _iterator2 = _createForOfIteratorHelper(renderedNodes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _step2.value, + to = _step2$value.to, + vnode = _step2$value.vnode; + addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + if (slots) { + for (var slotName in slots) { + var tagName = slotName === 'default' ? 'head' : slotName; // Only teleport the contents of head/body slots + + if (tagName !== 'head' && tagName !== 'body') { + continue; + } + + var slot = slots[slotName]; + + if (isFunction(slot)) { + addVnode(this.isSSR, teleports, tagName, slot({ + metainfo: active + })); + } + } + } + + return Object.keys(teleports).map(function (to) { + var teleport = teleports[to]; + return h(Teleport, { + to: to + }, teleport); + }); + } + }]); + + return MetaManager; +}(); + +_defineProperty(MetaManager, "create", function (isSSR, config, resolver) { + var resolve = function resolve(options, contexts, active, key, pathSegments) { + if (isFunction(resolver)) { + return resolver(options, contexts, active, key, pathSegments); + } + + return resolver.resolve(options, contexts, active, key, pathSegments); + }; + + var active = reactive({}); + var mergedObject = createMergedObject(resolve, active); // TODO: validate resolver + + var manager = new MetaManager(isSSR, config, mergedObject, resolver); + return manager; +}); + +var defaultOptions = { + keyName: 'metaInfo' +}; +var createMixin = function createMixin(options) { + return { + created: function created() { + var instance = getCurrentInstance(); + + if (!(instance !== null && instance !== void 0 && instance.type) || !(options.keyName in instance.type)) { + return; + } + + var metaInfo = instance.type[options.keyName]; + + if (isFunction(metaInfo)) { + var computedMetaInfo = computed(metaInfo.bind(this)); + useMeta(computedMetaInfo); + } else { + useMeta(metaInfo); + } + } + }; +}; +var install = function install(app) { + var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var options = Object.assign({}, defaultOptions, _options); + app.mixin(createMixin(options)); }; export { createMetaManager, defaultResolver as deepestResolver, defaultConfig, getCurrentManager, install as plugin, resolveOption, useActiveMeta, useMeta }; diff --git a/dist/vue-meta.esm-browser.min.js b/dist/vue-meta.esm-browser.min.js index bc6cbdf5..d5362eba 100644 --- a/dist/vue-meta.esm-browser.min.js +++ b/dist/vue-meta.esm-browser.min.js @@ -5,4 +5,4 @@ * - All the amazing contributors * @license MIT */ -import{markRaw as t,h as e,getCurrentInstance as o,isProxy as r,watch as n,inject as s,defineComponent as i,reactive as c,onUnmounted as a,Teleport as u,Comment as l,computed as f}from"vue";const d=(t,e)=>(o,r)=>{let n=-1;if(r.reduce(((e,o,r)=>{const s=t(e,o);return s!==e?(n=r,s):e}),e),n>-1)return o[n]},p=d(((t,e)=>{const{depth:o}=e;return!t||o>t?o:t}));var m=Object.freeze({__proto__:null,setup:t=>{let e=0;if(t.vm){let{vm:o}=t;do{o.parent&&(e++,o=o.parent)}while(o&&o.parent&&o!==o.root)}t.depth=e},resolve:p});const b={body:{tag:"script",to:"body"},base:{valueAttribute:"href"},charset:{tag:"meta",nameless:!0,valueAttribute:"charset"},description:{tag:"meta"},og:{group:!0,namespacedAttribute:!0,tag:"meta",keyAttribute:"property"},twitter:{group:!0,namespacedAttribute:!0,tag:"meta"},htmlAttrs:{attributesFor:"html"},headAttrs:{attributesFor:"head"},bodyAttrs:{attributesFor:"body"}},h={title:{attributes:!1},base:{contentAsAttribute:!0,attributes:["href","target"]},meta:{contentAsAttribute:!0,keyAttribute:"name",attributes:["content","name","http-equiv","charset"]},link:{contentAsAttribute:!0,attributes:["href","crossorigin","rel","media","integrity","hreflang","type","referrerpolicy","sizes","imagesrcset","imagesizes","as","color"]},style:{attributes:["media"]},script:{attributes:["src","type","nomodule","async","defer","crossorigin","integrity","referrerpolicy"]},noscript:{attributes:!1}};Object.freeze({}),Object.freeze([]);const g=Array.isArray,y=t=>"function"==typeof t,v=t=>"string"==typeof t,S=t=>null!==t&&"object"==typeof t,A=Object.prototype.toString,k=t=>"[object Object]"===A.call(t),N=Symbol("kIsProxy"),j=Symbol("kProxySources"),R=Symbol("kProxyTarget"),w=Symbol("kResolveContext");function x(t){if(g(t))return t.map(x);if(S(t)){const e={};for(const o in t)e[o]="context"===o?t[o]:x(t[o]);return e}return t}const O=(t,e,o)=>{const r=[];for(const n of t)n&&e in n&&(r.push(n[e]),o&&o(n));return r},$=(t,e=[],o,r)=>{if(!o&&!r&&(({active:o,sources:r}=t),e.length))for(let t=0;tt[n])).filter(Boolean)}if(!o||!r)return;const n=((t,...e)=>{const o=t?Object.keys(t):[];if(e)for(const t of e)if(t&&S(t))for(const e in t)o.includes(e)||o.push(e);return o})(...r),s=Object.keys(o);for(const t of s)n.includes(t)||delete o[t];for(const s of n){let n=!1;for(let t=0;ti.push(t[w])));let a=t.resolve(c,i,o[s],s,e);k(a)&&(a=x(a)),o[s]=a}},P=(e,o,r,n=[])=>{const s=C(e,r,n),i=t(new Proxy(o,s));return!n.length&&e.sources&&e.sources.push(i),i},C=(t,e,o=[])=>({get:(r,n,s)=>{if(n===N)return!0;if(n===j)return t.sources;if(n===R)return r;if(n===w)return e;let i=Reflect.get(r,n,s);if(!S(i))return i;if(!i[N]){const s=[...o,n];i=P(t,i,e,s),Reflect.set(r,n,i)}return i},set:(e,r,n)=>{const s=Reflect.set(e,r,n);if(s){const i=g(e);let c,a=!1,{sources:u,active:l}=t,f=0;for(const t of o){if(u=O(u,t),i&&f===o.length-1){c=t;break}g(l)&&(a=!0),l=l[t],f++}if(a)return $(t),s;if(k(n))return $(t,o),s;let d,p=[];i?(d=u,p=u.map((t=>t[w]))):d=O(u,r,(t=>p.push(t[w])));let m=t.resolve(d,p,l,r,o);k(m)&&(m=x(m)),i&&c?l[c]=m:l[r]=m}return s},deleteProperty:(e,r)=>{const n=Reflect.deleteProperty(e,r);if(n){const n=g(e);let s,i=t.sources,c=t.active,a=0;for(const t of o){if(i=i.map((e=>e&&e[t])),n&&a===o.length-1){s=t;break}c=c[t],a++}if(i.some((t=>t&&r in t))){let e,a=[];n?(e=i,a=i.map((t=>t[w]))):e=O(i,r,(t=>a.push(t[w])));let u=t.resolve(e,a,c,r,o);k(u)&&(u=x(u)),n&&s?c[s]=u:c[r]=u}else delete c[r]}return n}}),M={};function F(t,o,r,n){return"attributesFor"in n?function(t,o,r,n){const{attributesFor:s}=n;if(!s||!r)return;if(t.isSSR)return{to:"",vnode:e(`ssr-${s}`,r)};if(!M[s]){const[t,e]=Array.from(document.querySelectorAll(s));if(!t)return void console.error("Could not find element for selector",s,", won't render attributes");e&&console.warn("Found multiple elements for selector",s),M[s]={el:t,attrs:[]}}const{el:i,attrs:c}=M[s];for(const e in r){let n=U(t,`${o}(${e})`,r[e],r);g(n)&&(n=n.join(",")),i.setAttribute(e,n||""),c.includes(e)||c.push(e)}const a=c.filter((t=>!r[t]));for(const t of a)i.removeAttribute(t)}(t,o,r,n):"group"in n?function(t,e,o,r){if(g(o))return console.warn("Specifying an array for group properties isnt supported"),[];return Object.keys(o).map((n=>{const s={group:e,data:o};if(r.namespaced)s.tagNamespace=!0===r.namespaced?e:r.namespaced;else if(r.namespacedAttribute){const t=!0===r.namespacedAttribute?e:r.namespacedAttribute;s.fullName=`${t}:${n}`,s.slotName=`${t}(${n})`}return E(t,e,o[n],r,s)})).filter(Boolean).flat()}(t,o,r,n):E(t,o,r,n)}function E(t,o,r,n={},s){const i=["content","json","rawContent"],c=t=>function(t,e){for(const o of t){const t=h[o];if(o&&t)return t[e]}}([a,n.tag],t);if(g(r))return r.map((e=>E(t,o,e,n,s))).filter(Boolean).flat();const{tag:a=n.tag||o}=r;let u="",l=!1,f=!1;if(v(r))u=r;else if(r.children&&g(r.children))l=!0,u=r.children.map((e=>{const r=E(t,o,e,n,s);return g(r)?r.map((({vnode:t})=>t)):r&&r.vnode}));else{let t=0;for(const e of i){if(!u&&r[e]){u=1===t?JSON.stringify(r[e]):r[e],f=t>1;break}t++}}const d=s&&s.fullName||o,p=s&&s.slotName||o;let{attrs:m}=r;if(m||"object"!=typeof r)m||(m={});else{m={...r},delete m.tag,delete m.children,delete m.to;for(const t of i)delete m[t]}if(l)u=U(t,p,u,r);else{const e=!!c("contentAsAttribute");let{valueAttribute:o}=n;if(!o&&e){const[t]=c("attributes");o=v(e)?e:t}if(o){const{nameless:e}=n;if(!e){const t=n.keyAttribute||c("keyAttribute");t&&(m[t]=d)}m[o]=U(t,p,m[o]||u,s),u=""}else u=U(t,p,u,r)}const b=s&&s.tagNamespace?`${s.tagNamespace}:${a}`:a;if("title"===b&&!t.isSSR)return void(document.title=u);f&&u&&(m.innerHTML=u);const y=e(b,m,u||void 0);return{to:r.to,vnode:y}}function U({metainfo:t,slots:e},o,r,n){const s=e&&e[o];if(!s||!y(s))return r;const i={content:r,metainfo:t};if(n&&n.group){const{group:t,data:e}=n;i[t]=e}const c=s(i);if(c&&c.length){const{children:t}=c[0];return t?t.toString():""}return r}const z="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,_=(t=>z?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function L(t,e,o){for(const r in e)r in o?S(t[r])?L(t[r],e[r],o[r]):e[r]!==o[r]&&(t[r]=e[r]):t[r]=e[r];for(const r in o)e&&r in e||delete t[r]}function q(t){if(t||(t=o()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function B(t,e){const s=o()||void 0;if(!e&&s&&(e=q(s)),!e)throw new Error("No manager or current instance");r(t)&&(n(t,((t,e)=>{L(i.meta,t,e)})),t=t.value);const i=e.addMeta(t,s);return i}function I(){return s(_)}const T=i({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=q();if(t)return t.render({slots:e})}});function D(t,e,o,r){const n=g(r)?r:[r];t?o.endsWith("Attrs")||n.forEach((t=>{t.props||(t.props={}),t.props["data-vm-ssr"]=!0})):n.forEach(((t,e)=>{t.type===l&&n.splice(e,1)})),e[o]||(e[o]=[]),e[o].push(...n)}const H=(t=!1,e,o)=>J.create(t,e||b,o||m);class J{isSSR=!1;config;target;resolver;ssrCleanedUp=!1;constructor(t,e,o,r){this.isSSR=t,this.config=e,this.target=o,r&&"setup"in r&&y(r.setup)&&(this.resolver=r)}static create=(t,e,o)=>{const r=((t,e)=>{const o=[],r={active:e,resolve:t,sources:o},n=()=>$(r);return{context:r,compute:n,addSource:(t,e,o=!1)=>{const s=P(r,t,e||{});return o&&n(),s},delSource:(t,e=!0)=>{const r=o.findIndex((e=>e===t||e[R]===t));return r>-1&&(o.splice(r,1),e&&n(),!0)}}})(((t,e,r,n,s)=>y(o)?o(t,e,r,n,s):o.resolve(t,e,r,n,s)),c({}));return new J(t,e,r,o)};install(t){t.component("Metainfo",T),t.config.globalProperties.$metaManager=this,t.provide(_,this.target.context.active)}addMeta(t,e){e||(e=o()||void 0);const r={removed:[]},n={vm:e},{resolver:s}=this;s&&s.setup&&s.setup(n);const i=this.target.addSource(t,n,!0),c=t=>this.unmount(!!t,i,r,e);return e&&a(c),{meta:i,onRemoved:t=>r.removed.push(t),unmount:c}}unmount(t,e,o,r){if(r){const{$el:n}=r.proxy;if(n&&n.offsetParent){let r=new MutationObserver((s=>{for(const{removedNodes:i}of s)i&&i.forEach((s=>{s===n&&r&&(r.disconnect(),r=void 0,this.reallyUnmount(t,e,o))}))}));return void r.observe(n.parentNode,{childList:!0})}}this.reallyUnmount(t,e,o)}async reallyUnmount(t,e,o){this.target.delSource(e),!t&&o&&await Promise.all(o.removed.map((t=>t())))}render({slots:t}={}){const o=this.target.context.active,{isSSR:r}=this;if(!r&&!this.ssrCleanedUp){this.ssrCleanedUp=!0;const t=()=>{const t=document.querySelectorAll("[data-vm-ssr]");t&&t.length&&t.forEach((t=>t.parentNode&&t.parentNode.removeChild(t)))};"loading"===document.readyState?window.addEventListener("DOMContentLoaded",t,{once:!0}):t()}const n={};for(const e in o){const s=this.config[e]||{};let i=F({isSSR:r,metainfo:o,slots:t},e,o[e],s);if(!i)continue;g(i)||(i=[i]);let c="base"!==e&&o[e].to;!c&&"to"in s&&(c=s.to),!c&&"attributesFor"in s&&(c=e);for(const{to:t,vnode:e}of i)D(this.isSSR,n,t||c||"head",e)}if(t)for(const e in t){const r="default"===e?"head":e;if("head"!==r&&"body"!==r)continue;const s=t[e];y(s)&&D(this.isSSR,n,r,s({metainfo:o}))}return Object.keys(n).map((t=>e(u,{to:t},n[t])))}}const W={keyName:"metaInfo"},G=t=>({created(){const e=o();if(!e?.type||!(t.keyName in e.type))return;const r=e.type[t.keyName];if(y(r)){B(f(r.bind(this)))}else B(r)}}),K=(t,e={})=>{const o=Object.assign({},W,e);t.mixin(G(o))};export{H as createMetaManager,m as deepestResolver,b as defaultConfig,q as getCurrentManager,K as plugin,d as resolveOption,I as useActiveMeta,B as useMeta}; +import t from"@babel/runtime/helpers/asyncToGenerator";import r from"@babel/runtime/helpers/classCallCheck";import e from"@babel/runtime/helpers/createClass";import n from"@babel/runtime/helpers/defineProperty";import o from"@babel/runtime/helpers/toConsumableArray";import a from"@babel/runtime/regenerator";import{markRaw as i,h as u,getCurrentInstance as f,isProxy as c,watch as l,inject as s,defineComponent as v,reactive as y,onUnmounted as d,Teleport as p,Comment as m,computed as h}from"vue";import b from"@babel/runtime/helpers/typeof";import g from"@babel/runtime/helpers/slicedToArray";var A=function(t,r){return function(e,n){var o=-1;if(n.reduce((function(r,e,n){var a=t(r,e);return a!==r?(o=n,a):r}),r),o>-1)return e[o]}},S=A((function(t,r){var e=r.depth;return!t||e>t?e:t})),w=Object.freeze({__proto__:null,setup:function(t){var r=0;if(t.vm){var e=t.vm;do{e.parent&&(r++,e=e.parent)}while(e&&e.parent&&e!==e.root)}t.depth=r},resolve:S}),j={body:{tag:"script",to:"body"},base:{valueAttribute:"href"},charset:{tag:"meta",nameless:!0,valueAttribute:"charset"},description:{tag:"meta"},og:{group:!0,namespacedAttribute:!0,tag:"meta",keyAttribute:"property"},twitter:{group:!0,namespacedAttribute:!0,tag:"meta"},htmlAttrs:{attributesFor:"html"},headAttrs:{attributesFor:"head"},bodyAttrs:{attributesFor:"body"}},O={title:{attributes:!1},base:{contentAsAttribute:!0,attributes:["href","target"]},meta:{contentAsAttribute:!0,keyAttribute:"name",attributes:["content","name","http-equiv","charset"]},link:{contentAsAttribute:!0,attributes:["href","crossorigin","rel","media","integrity","hreflang","type","referrerpolicy","sizes","imagesrcset","imagesizes","as","color"]},style:{attributes:["media"]},script:{attributes:["src","type","nomodule","async","defer","crossorigin","integrity","referrerpolicy"]},noscript:{attributes:!1}};function k(t,r){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!e){if(Array.isArray(t)||(e=function(t,r){if(!t)return;if("string"==typeof t)return x(t,r);var e=Object.prototype.toString.call(t).slice(8,-1);"Object"===e&&t.constructor&&(e=t.constructor.name);if("Map"===e||"Set"===e)return Array.from(t);if("Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e))return x(t,r)}(t))||r&&t&&"number"==typeof t.length){e&&(t=e);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){e=e.call(t)},n:function(){var t=e.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==e.return||e.return()}finally{if(u)throw a}}}}function x(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e"function"==typeof t,E=t=>"string"==typeof t,N=t=>null!==t&&"object"==typeof t,M=Object.prototype.toString,R=t=>"[object Object]"===M.call(t);var U=Symbol("kIsProxy"),T=Symbol("kProxySources"),$=Symbol("kProxyTarget"),F=Symbol("kResolveContext");function D(t){if(C(t))return t.map(D);if(N(t)){var r={};for(var e in t)r[e]="context"===e?t[e]:D(t[e]);return r}return t}function z(t,r){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!e){if(Array.isArray(t)||(e=function(t,r){if(!t)return;if("string"==typeof t)return _(t,r);var e=Object.prototype.toString.call(t).slice(8,-1);"Object"===e&&t.constructor&&(e=t.constructor.name);if("Map"===e||"Set"===e)return Array.from(t);if("Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e))return _(t,r)}(t))||r&&t&&"number"==typeof t.length){e&&(t=e);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){e=e.call(t)},n:function(){var t=e.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==e.return||e.return()}finally{if(u)throw a}}}}function _(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){e=e.call(t)},n:function(){var t=e.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==e.return||e.return()}finally{if(u)throw a}}}}function q(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e1&&void 0!==arguments[1]&&arguments[1],n=function(){try{throw new Error("DEBUG")}catch(o){for(var t=arguments.length,e=new Array(t),n=0;n1?e-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2?arguments[2]:void 0,a=arguments.length>3?arguments[3]:void 0,i=!n&&!a;if(i&&(n=r.active,a=r.sources,e.length))for(var u=function(t){var r=e[t];if(!n||!n[r])return console.error("recompute: segment ".concat(r," not found on target"),e,n),{v:void 0};n=n[r],a=a.map((function(t){return t[r]})).filter(Boolean)},f=0;f=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){e=e.call(t)},n:function(){var t=e.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==e.return||e.return()}finally{if(u)throw a}}}}function W(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e3&&void 0!==arguments[3]?arguments[3]:[],o=Q(t,e,n),a=i(new Proxy(r,o));return!n.length&&t.sources&&t.sources.push(a),a},Q=function(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return{get:function(n,a,i){if(a===U)return!0;if(a===T)return t.sources;if(a===$)return n;if(a===F)return r;var u=Reflect.get(n,a,i);if(!N(u))return u;if(!u[U]){var f=[].concat(o(e),[a]);u=K(t,u,r,f),Reflect.set(n,a,u)}return u},set:function(r,n,o){var a=Reflect.set(r,n,o);if(a){var i,u,f=C(r),c=!1,l=t.sources,s=t.active,v=0,y=J(e);try{for(y.s();!(u=y.n()).done;){var d=u.value;if(l=B(l,d),f&&v===e.length-1){i=d;break}C(s)&&(c=!0),s=s[d],v++}}catch(t){y.e(t)}finally{y.f()}if(c)return H(t),a;if(R(o))return H(t,e),a;var p,m=[];f?(p=l,m=l.map((function(t){return t[F]}))):p=B(l,n,(function(t){return m.push(t[F])}));var h=t.resolve(p,m,s,n,e);R(h)&&(h=D(h)),f&&i?s[i]=h:s[n]=h}return a},deleteProperty:function(r,n){var o=Reflect.deleteProperty(r,n);if(o){var a,i,u=C(r),f=t.sources,c=t.active,l=0,s=J(e);try{var v=function(){var t=i.value;if(f=f.map((function(r){return r&&r[t]})),u&&l===e.length-1)return a=t,"break";c=c[t],l++};for(s.s();!(i=s.n()).done;){if("break"===v())break}}catch(t){s.e(t)}finally{s.f()}if(f.some((function(t){return t&&n in t}))){var y,d=[];u?(y=f,d=f.map((function(t){return t[F]}))):y=B(f,n,(function(t){return d.push(t[F])}));var p=t.resolve(y,d,c,n,e);R(p)&&(p=D(p)),u&&a?c[a]=p:c[n]=p}else delete c[n]}return o}}};function V(t,r){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(t,r).enumerable}))),e.push.apply(e,n)}return e}function X(t){for(var r=1;r=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){e=e.call(t)},n:function(){var t=e.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==e.return||e.return()}finally{if(u)throw a}}}}function Z(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e3&&void 0!==arguments[3]?arguments[3]:{},o=arguments.length>4?arguments[4]:void 0,a=["content","json","rawContent"],i=function(t){return I([c,n.tag],t)};if(C(e))return e.map((function(e){return et(t,r,e,n,o)})).filter(Boolean).flat();var f=e.tag,c=void 0===f?n.tag||r:f,l="",s=!1,v=!1;if(E(e))l=e;else if(e.children&&C(e.children))s=!0,l=e.children.map((function(e){var a=et(t,r,e,n,o);return C(a)?a.map((function(t){return t.vnode})):a&&a.vnode}));else{var y,d=0,p=Y(a);try{for(p.s();!(y=p.n()).done;){var m=y.value;if(!l&&e[m]){l=1===d?JSON.stringify(e[m]):e[m],v=d>1;break}d++}}catch(t){p.e(t)}finally{p.f()}}var h=o&&o.fullName||r,A=o&&o.slotName||r,S=e.attrs;if(S||"object"!==b(e))S||(S={});else{delete(S=X({},e)).tag,delete S.children,delete S.to;var w,j=Y(a);try{for(j.s();!(w=j.n()).done;){var O=w.value;delete S[O]}}catch(t){j.e(t)}finally{j.f()}}if(s)l=nt(t,A,l,e);else{var k=!!i("contentAsAttribute"),x=n.valueAttribute;if(!x&&k){var P=i("attributes"),N=g(P,1),M=N[0];x=E(k)?k:M}if(x){var R=n.nameless;if(!R){var U=n.keyAttribute||i("keyAttribute");U&&(S[U]=h)}S[x]=nt(t,A,S[x]||l,o),l=""}else l=nt(t,A,l,e)}var T=o&&o.tagNamespace?"".concat(o.tagNamespace,":").concat(c):c;if("title"!==T||t.isSSR){v&&l&&(S.innerHTML=l);var $=u(T,S,l||void 0);return{to:e.to,vnode:$}}document.title=l}function nt(t,r,e,n){var o=t.metainfo,a=t.slots,i=a&&a[r];if(!i||!P(i))return e;var u={content:e,metainfo:o};n&&n.group&&(u[n.group]=n.data);var f=i(u);if(f&&f.length){var c=f[0].children;return c?c.toString():""}return e}var ot="function"==typeof Symbol&&"symbol"===b(Symbol.toStringTag),at=function(t){return ot?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t}("meta_active");function it(t,r,e){for(var n in r)n in e?N(t[n])?it(t[n],r[n],e[n]):r[n]!==e[n]&&(t[n]=r[n]):t[n]=r[n];for(var o in e)r&&o in r||delete t[o]}function ut(t){if(t||(t=f()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function ft(t,r){var e=f()||void 0;if(!r&&e&&(r=ut(e)),!r)throw new Error("No manager or current instance");c(t)&&(l(t,(function(t,r){it(n.meta,t,r)})),t=t.value);var n=r.addMeta(t,e);return n}function ct(){return s(at)}var lt=v({name:"Metainfo",inheritAttrs:!1,setup:function(t,r){var e=r.slots;return function(){var t=ut();if(t)return t.render({slots:e})}}});function st(t,r){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!e){if(Array.isArray(t)||(e=function(t,r){if(!t)return;if("string"==typeof t)return vt(t,r);var e=Object.prototype.toString.call(t).slice(8,-1);"Object"===e&&t.constructor&&(e=t.constructor.name);if("Map"===e||"Set"===e)return Array.from(t);if("Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e))return vt(t,r)}(t))||r&&t&&"number"==typeof t.length){e&&(t=e);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){e=e.call(t)},n:function(){var t=e.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==e.return||e.return()}finally{if(u)throw a}}}}function vt(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e0&&void 0!==arguments[0]&&arguments[0],r=arguments.length>1?arguments[1]:void 0,e=arguments.length>2?arguments[2]:void 0;return pt.create(t,r||j,e||w)},pt=function(){function o(t,e,a,i){r(this,o),n(this,"isSSR",!1),n(this,"config",void 0),n(this,"target",void 0),n(this,"resolver",void 0),n(this,"ssrCleanedUp",!1),this.isSSR=t,this.config=e,this.target=a,i&&"setup"in i&&P(i.setup)&&(this.resolver=i)}var i;return e(o,[{key:"install",value:function(t){t.component("Metainfo",lt),t.config.globalProperties.$metaManager=this,t.provide(at,this.target.context.active)}},{key:"addMeta",value:function(t,r){var e=this;r||(r=f()||void 0);var n={removed:[]},o={vm:r},a=this.resolver;a&&a.setup&&a.setup(o);var i=this.target.addSource(t,o,!0),u=function(t){return e.unmount(!!t,i,n,r)};return r&&d(u),{meta:i,onRemoved:function(t){return n.removed.push(t)},unmount:u}}},{key:"unmount",value:function(t,r,e,n){var o=this;if(n){var a=n.proxy.$el;if(a&&a.offsetParent){var i=new MutationObserver((function(n){var u,f=st(n);try{for(f.s();!(u=f.n()).done;){var c=u.value.removedNodes;c&&c.forEach((function(n){n===a&&i&&(i.disconnect(),i=void 0,o.reallyUnmount(t,r,e))}))}}catch(t){f.e(t)}finally{f.f()}}));return void i.observe(a.parentNode,{childList:!0})}}this.reallyUnmount(t,r,e)}},{key:"reallyUnmount",value:(i=t(a.mark((function t(r,e,n){return a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this.target.delSource(e),r||!n){t.next=4;break}return t.next=4,Promise.all(n.removed.map((function(t){return t()})));case 4:case"end":return t.stop()}}),t,this)}))),function(t,r,e){return i.apply(this,arguments)})},{key:"render",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=t.slots,e=this.target.context.active,n=this.isSSR;if(!n&&!this.ssrCleanedUp){this.ssrCleanedUp=!0;var o=function(){var t=document.querySelectorAll("[".concat("data-vm-ssr","]"));t&&t.length&&t.forEach((function(t){return t.parentNode&&t.parentNode.removeChild(t)}))};"loading"===document.readyState?window.addEventListener("DOMContentLoaded",o,{once:!0}):o()}var a={};for(var i in e){var f=this.config[i]||{},c=rt({isSSR:n,metainfo:e,slots:r},i,e[i],f);if(c){C(c)||(c=[c]);var l="base"!==i&&e[i].to;!l&&"to"in f&&(l=f.to),!l&&"attributesFor"in f&&(l=i);var s,v=st(c);try{for(v.s();!(s=v.n()).done;){var y=s.value,d=y.to,m=y.vnode;yt(this.isSSR,a,d||l||"head",m)}}catch(t){v.e(t)}finally{v.f()}}}if(r)for(var h in r){var b="default"===h?"head":h;if("head"===b||"body"===b){var g=r[h];P(g)&&yt(this.isSSR,a,b,g({metainfo:e}))}}return Object.keys(a).map((function(t){return u(p,{to:t},a[t])}))}}]),o}();n(pt,"create",(function(t,r,e){var n=function(t,r){var e=[],n={active:r,resolve:t,sources:e},o=function(){return H(n)};return{context:n,compute:o,addSource:function(t,r){var e=arguments.length>2&&void 0!==arguments[2]&&arguments[2],a=K(n,t,r||{});return e&&o(),a},delSource:function(t){var r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=e.findIndex((function(r){return r===t||r[$]===t}));return n>-1&&(e.splice(n,1),r&&o(),!0)}}}((function(t,r,n,o,a){return P(e)?e(t,r,n,o,a):e.resolve(t,r,n,o,a)}),y({}));return new pt(t,r,n,e)}));var mt={keyName:"metaInfo"},ht=function(t){return{created:function(){var r=f();if(null!=r&&r.type&&t.keyName in r.type){var e=r.type[t.keyName];if(P(e))ft(h(e.bind(this)));else ft(e)}}}},bt=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=Object.assign({},mt,r);t.mixin(ht(e))};export{dt as createMetaManager,w as deepestResolver,j as defaultConfig,ut as getCurrentManager,bt as plugin,A as resolveOption,ct as useActiveMeta,ft as useMeta}; diff --git a/dist/vue-meta.esm-bundler.js b/dist/vue-meta.esm-bundler.js index a0d22ef1..923545cd 100644 --- a/dist/vue-meta.esm-bundler.js +++ b/dist/vue-meta.esm-bundler.js @@ -6,42 +6,60 @@ * @license MIT */ +import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator'; +import _classCallCheck from '@babel/runtime/helpers/classCallCheck'; +import _createClass from '@babel/runtime/helpers/createClass'; +import _defineProperty from '@babel/runtime/helpers/defineProperty'; +import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; +import _regeneratorRuntime from '@babel/runtime/regenerator'; import { markRaw, h, getCurrentInstance, isProxy, watch, inject, defineComponent, reactive, onUnmounted, Teleport, Comment, computed } from 'vue'; +import _typeof from '@babel/runtime/helpers/typeof'; +import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; -const resolveOption = (predicament, initialValue) => (options, contexts) => { - let resolvedIndex = -1; - contexts.reduce((acc, context, index) => { - const retval = predicament(acc, context); - if (retval !== acc) { - resolvedIndex = index; - return retval; - } - return acc; - }, initialValue); - if (resolvedIndex > -1) { - return options[resolvedIndex]; - } +var resolveOption = function resolveOption(predicament, initialValue) { + return function (options, contexts) { + var resolvedIndex = -1; + contexts.reduce(function (acc, context, index) { + var retval = predicament(acc, context); + + if (retval !== acc) { + resolvedIndex = index; + return retval; + } + + return acc; + }, initialValue); + + if (resolvedIndex > -1) { + return options[resolvedIndex]; + } + }; }; -const setup = (context) => { - let depth = 0; - if (context.vm) { - let { vm } = context; - do { - if (vm.parent) { - depth++; - vm = vm.parent; - } - } while (vm && vm.parent && vm !== vm.root); - } - context.depth = depth; -}; -const resolve = resolveOption((currentValue, context) => { - const { depth } = context; - if (!currentValue || depth > currentValue) { - return depth; - } - return currentValue; +var setup = function setup(context) { + var depth = 0; + + if (context.vm) { + var vm = context.vm; + + do { + if (vm.parent) { + depth++; + vm = vm.parent; + } + } while (vm && vm.parent && vm !== vm.root); + } + + context.depth = depth; +}; +var resolve = resolveOption(function (currentValue, context) { + var depth = context.depth; + + if (!currentValue || depth > currentValue) { + return depth; + } + + return currentValue; }); var defaultResolver = /*#__PURE__*/Object.freeze({ @@ -50,105 +68,98 @@ var defaultResolver = /*#__PURE__*/Object.freeze({ resolve: resolve }); -const defaultConfig = { - body: { - tag: 'script', - to: 'body' - }, - base: { - valueAttribute: 'href' - }, - charset: { - tag: 'meta', - nameless: true, - valueAttribute: 'charset' - }, - description: { - tag: 'meta' - }, - og: { - group: true, - namespacedAttribute: true, - tag: 'meta', - keyAttribute: 'property' - }, - twitter: { - group: true, - namespacedAttribute: true, - tag: 'meta' - }, - htmlAttrs: { - attributesFor: 'html' - }, - headAttrs: { - attributesFor: 'head' - }, - bodyAttrs: { - attributesFor: 'body' - } +var defaultConfig = { + body: { + tag: 'script', + to: 'body' + }, + base: { + valueAttribute: 'href' + }, + charset: { + tag: 'meta', + nameless: true, + valueAttribute: 'charset' + }, + description: { + tag: 'meta' + }, + og: { + group: true, + namespacedAttribute: true, + tag: 'meta', + keyAttribute: 'property' + }, + twitter: { + group: true, + namespacedAttribute: true, + tag: 'meta' + }, + htmlAttrs: { + attributesFor: 'html' + }, + headAttrs: { + attributesFor: 'head' + }, + bodyAttrs: { + attributesFor: 'body' + } }; /* * This is a fixed config for real HTML tags - */ -const tags = { - title: { - attributes: false - }, - base: { - contentAsAttribute: true, - attributes: ['href', 'target'] - }, - meta: { - contentAsAttribute: true, - keyAttribute: 'name', - attributes: ['content', 'name', 'http-equiv', 'charset'] - }, - link: { - contentAsAttribute: true, - attributes: [ - 'href', - 'crossorigin', - 'rel', - 'media', - 'integrity', - 'hreflang', - 'type', - 'referrerpolicy', - 'sizes', - 'imagesrcset', - 'imagesizes', - 'as', - 'color' - ] - }, - style: { - attributes: ['media'] - }, - script: { - attributes: [ - 'src', - 'type', - 'nomodule', - 'async', - 'defer', - 'crossorigin', - 'integrity', - 'referrerpolicy' - ] - }, - noscript: { - attributes: false - } + */ +var tags = { + title: { + attributes: false + }, + base: { + contentAsAttribute: true, + attributes: ['href', 'target'] + }, + meta: { + contentAsAttribute: true, + keyAttribute: 'name', + attributes: ['content', 'name', 'http-equiv', 'charset'] + }, + link: { + contentAsAttribute: true, + attributes: ['href', 'crossorigin', 'rel', 'media', 'integrity', 'hreflang', 'type', 'referrerpolicy', 'sizes', 'imagesrcset', 'imagesizes', 'as', 'color'] + }, + style: { + attributes: ['media'] + }, + script: { + attributes: ['src', 'type', 'nomodule', 'async', 'defer', 'crossorigin', 'integrity', 'referrerpolicy'] + }, + noscript: { + attributes: false + } }; -function getTagConfigItem(tagOrName, key) { - for (const name of tagOrName) { - const tag = tags[name]; - if (name && tag) { - return tag[key]; - } - } +function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(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$5(o, minLen); } + +function _arrayLikeToArray$5(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 getTagConfigItem(tagOrName, key) { + var _iterator = _createForOfIteratorHelper$5(tagOrName), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var name = _step.value; + var tag = tags[name]; + + if (name && tag) { + return tag[key]; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } } /** @@ -158,6 +169,7 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ + Object.freeze({}) ; Object.freeze([]) ; @@ -169,805 +181,1275 @@ const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const isPlainObject = (val) => toTypeString(val) === '[object Object]'; -// https://github.com/microsoft/TypeScript/issues/1863 -const IS_PROXY = Symbol('kIsProxy'); -const PROXY_SOURCES = Symbol('kProxySources'); -const PROXY_TARGET = Symbol('kProxyTarget'); -const RESOLVE_CONTEXT = Symbol('kResolveContext'); - -// See: https://github.com/vuejs/vue-next/blob/08b4e8815da4e8911058ccbab986bea6365c3352/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts -function clone(v) { - if (isArray(v)) { - return v.map(clone); - } - if (isObject(v)) { - const res = {}; - for (const key in v) { - // never clone the context - if (key === 'context') { - res[key] = v[key]; - } - else { - res[key] = clone(v[key]); - } - } - return res; - } - return v; +// https://github.com/microsoft/TypeScript/issues/1863 +var IS_PROXY = Symbol('kIsProxy'); +var PROXY_SOURCES = Symbol('kProxySources'); +var PROXY_TARGET = Symbol('kProxyTarget'); +var RESOLVE_CONTEXT = Symbol('kResolveContext'); + +function clone(v) { + if (isArray(v)) { + return v.map(clone); + } + + if (isObject(v)) { + var res = {}; + + for (var key in v) { + // never clone the context + if (key === 'context') { + res[key] = v[key]; + } else { + res[key] = clone(v[key]); + } + } + + return res; + } + + return v; } -const pluck = (collection, key, callback) => { - const plucked = []; - for (const row of collection) { - if (row && key in row) { - plucked.push(row[key]); - if (callback) { - callback(row); - } - } - } - return plucked; +function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(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$4(o, minLen); } + +function _arrayLikeToArray$4(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; } + +var pluck = function pluck(collection, key, callback) { + var plucked = []; + + var _iterator = _createForOfIteratorHelper$4(collection), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var row = _step.value; + + if (row && key in row) { + plucked.push(row[key]); + + if (callback) { + callback(row); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return plucked; }; -const allKeys = (source, ...sources) => { - const keys = source ? Object.keys(source) : []; - if (sources) { - for (const source of sources) { - if (!source || !isObject(source)) { - continue; - } - for (const key in source) { - if (!keys.includes(key)) { - keys.push(key); - } - } - } - } - // TODO: add check for consistent types for each key (dev only) - return keys; -}; -const recompute = (context, path = [], target, sources) => { - const setTargetAndSources = !target && !sources; - if (setTargetAndSources) { - ({ active: target, sources } = context); - if (path.length) { - for (let i = 0; i < path.length; i++) { - const seg = path[i]; - if (!target || !target[seg]) { - if (("development" !== 'production')) { - // eslint-disable-next-line no-console - console.error(`recompute: segment ${seg} not found on target`, path, target); - } - return; - } - target = target[seg]; - sources = sources.map(source => source[seg]).filter(Boolean); - } - } - } - if (!target || !sources) { - return; - } - const keys = allKeys(...sources); - // Clean up properties that dont exists anymore - const targetKeys = Object.keys(target); - for (const key of targetKeys) { - if (!keys.includes(key)) { - delete target[key]; - } - } - for (const key of keys) { - // This assumes consistent types usages for keys across sources - // @ts-ignore - let isObject = false; - for (let i = 0; i < sources.length; i++) { - const source = sources[i]; - if (source && key in source && source[key] !== undefined) { - isObject = isPlainObject(source[key]); - break; - } - } - if (isObject) { - if (!target[key]) { - target[key] = {}; - } - const keySources = []; - for (const source of sources) { - if (key in source) { - // @ts-ignore - keySources.push(source[key]); - } - } - recompute(context, [...path, key], target[key], keySources); - continue; - } - // Ensure the target is an array if source is an array and target is empty - // @ts-ignore - if (!target[key] && isArray(sources[0][key])) { - target[key] = []; - } - const keyContexts = []; - const keySources = pluck(sources, key, source => keyContexts.push(source[RESOLVE_CONTEXT])); - let resolved = context.resolve(keySources, keyContexts, target[key], key, path); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - target[key] = resolved; - } +var debugFn = function debugFn(logFn) { + var setChildFns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fn = function fn() { + try { + throw new Error('DEBUG'); + } catch (err) { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logFn.apply(void 0, args.concat(['\n', err])); + } + }; + + if (setChildFns) { + fn.warn = debugFn(console.warn); // eslint-disable-line no-console + + fn.error = debugFn(console.error); // eslint-disable-line no-console + } + + return fn; }; +debugFn(console.log, true); // eslint-disable-line no-console -const createProxy = (context, target, resolveContext, pathSegments = []) => { - const handler = createHandler(context, resolveContext, pathSegments); - const proxy = markRaw(new Proxy(target, handler)); - if (!pathSegments.length && context.sources) { - context.sources.push(proxy); - } - return proxy; -}; -const createHandler = (context, resolveContext, pathSegments = []) => ({ - get: (target, key, receiver) => { - if (key === IS_PROXY) { - return true; - } - if (key === PROXY_SOURCES) { - return context.sources; - } - if (key === PROXY_TARGET) { - return target; - } - if (key === RESOLVE_CONTEXT) { - return resolveContext; - } - let value = Reflect.get(target, key, receiver); - if (!isObject(value)) { - return value; - } - // Also return a merge proxy for nested objects - if (!value[IS_PROXY]) { - const keyPath = [...pathSegments, key]; - value = createProxy(context, value, resolveContext, keyPath); - Reflect.set(target, key, value); - } - return value; - }, - set: (target, key, value) => { - const success = Reflect.set(target, key, value); - // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) - if (success) { - const isArrayItem = isArray(target); - let hasArrayParent = false; - let { sources: proxies, active } = context; - let activeSegmentKey; - let index = 0; - for (const segment of pathSegments) { - proxies = pluck(proxies, segment); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - if (isArray(active)) { - hasArrayParent = true; - } - active = active[segment]; - index++; - } - if (hasArrayParent) { - // TODO: fix that we dont have to recompute the full merged object - // we should only have to recompute the branch that has changed - // but there is an issue here with supporting both arrays of strings - // as collections (parent vs parent of parent we need to trigger the - // update from) - recompute(context); - return success; - } - else if (isPlainObject(value)) { - // if an object was assigned to this key make sure to recompute all - // of its individual properies - recompute(context, pathSegments); - return success; - } - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - // Ensure to clone if value is an object, cause sources is an array of - // the sourceProxies and not the sources so we could trigger an endless loop when - // updating a prop on an obj as the prop on the active object refers to - // a prop on a proxy - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) - return success; - }, - deleteProperty: (target, key) => { - const success = Reflect.deleteProperty(target, key); - // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) - if (success) { - const isArrayItem = isArray(target); - let activeSegmentKey; - let proxies = context.sources; - let active = context.active; - let index = 0; - for (const segment of pathSegments) { - // @ts-ignore - proxies = proxies.map(proxy => proxy && proxy[segment]); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - active = active[segment]; - index++; - } - // Check if the key still exists in one of the sourceProxies, - // if so resolve the new value, if not remove the key - if (proxies.some(proxy => proxy && (key in proxy))) { - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', resolved) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - else { - delete active[key]; - } - } - return success; - } -}); +function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(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$3(o, minLen); } + +function _arrayLikeToArray$3(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; } +var allKeys = function allKeys(source) { + var keys = source ? Object.keys(source) : []; + + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (sources) { + var _iterator = _createForOfIteratorHelper$3(sources), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _source = _step.value; + + if (!_source || !isObject(_source)) { + continue; + } + + for (var key in _source) { + if (!keys.includes(key)) { + keys.push(key); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } // TODO: add check for consistent types for each key (dev only) + + + return keys; +}; +var recompute = function recompute(context) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var target = arguments.length > 2 ? arguments[2] : undefined; + var sources = arguments.length > 3 ? arguments[3] : undefined; + var setTargetAndSources = !target && !sources; + + if (setTargetAndSources) { + target = context.active; + sources = context.sources; + + if (path.length) { + var _loop = function _loop(i) { + var seg = path[i]; + + if (!target || !target[seg]) { + if ("development" !== 'production') { + // eslint-disable-next-line no-console + console.error("recompute: segment ".concat(seg, " not found on target"), path, target); + } + + return { + v: void 0 + }; + } + + target = target[seg]; + sources = sources.map(function (source) { + return source[seg]; + }).filter(Boolean); + }; + + for (var i = 0; i < path.length; i++) { + var _ret = _loop(i); + + if (_typeof(_ret) === "object") return _ret.v; + } + } + } + + if (!target || !sources) { + return; + } + + var keys = allKeys.apply(void 0, _toConsumableArray(sources)); // Clean up properties that dont exists anymore + + var targetKeys = Object.keys(target); + + for (var _i = 0, _targetKeys = targetKeys; _i < _targetKeys.length; _i++) { + var key = _targetKeys[_i]; + + if (!keys.includes(key)) { + delete target[key]; + } + } + + var _iterator2 = _createForOfIteratorHelper$3(keys), + _step2; + + try { + var _loop2 = function _loop2() { + var key = _step2.value; + // This assumes consistent types usages for keys across sources + // @ts-ignore + var isObject = false; + + for (var _i2 = 0; _i2 < sources.length; _i2++) { + var source = sources[_i2]; + + if (source && key in source && source[key] !== undefined) { + isObject = isPlainObject(source[key]); + break; + } + } + + if (isObject) { + if (!target[key]) { + target[key] = {}; + } + + var _keySources = []; + + var _iterator3 = _createForOfIteratorHelper$3(sources), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _source2 = _step3.value; + + if (key in _source2) { + // @ts-ignore + _keySources.push(_source2[key]); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + recompute(context, [].concat(_toConsumableArray(path), [key]), target[key], _keySources); + return "continue"; + } // Ensure the target is an array if source is an array and target is empty + // @ts-ignore + + + if (!target[key] && isArray(sources[0][key])) { + target[key] = []; + } + + var keyContexts = []; + var keySources = pluck(sources, key, function (source) { + return keyContexts.push(source[RESOLVE_CONTEXT]); + }); + var resolved = context.resolve(keySources, keyContexts, target[key], key, path); -const createMergedObject = (resolve, active) => { - const sources = []; - const context = { - active, - resolve, - sources - }; - const compute = () => recompute(context); - return { - context, - compute, - addSource: (source, resolveContext, recompute = false) => { - const proxy = createProxy(context, source, resolveContext || {}); - if (recompute) { - compute(); - } - return proxy; - }, - delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); - if (index > -1) { - sources.splice(index, 1); - if (recompute) { - compute(); - } - return true; - } - return false; - } - }; + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } + + target[key] = resolved; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret2 = _loop2(); + + if (_ret2 === "continue") continue; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } +}; + +function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(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$2(o, minLen); } + +function _arrayLikeToArray$2(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; } +var createProxy = function createProxy(context, target, resolveContext) { + var pathSegments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + var handler = createHandler(context, resolveContext, pathSegments); + var proxy = markRaw(new Proxy(target, handler)); + + if (!pathSegments.length && context.sources) { + context.sources.push(proxy); + } + + return proxy; +}; +var createHandler = function createHandler(context, resolveContext) { + var pathSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + return { + get: function get(target, key, receiver) { + if (key === IS_PROXY) { + return true; + } + + if (key === PROXY_SOURCES) { + return context.sources; + } + + if (key === PROXY_TARGET) { + return target; + } + + if (key === RESOLVE_CONTEXT) { + return resolveContext; + } + + var value = Reflect.get(target, key, receiver); + + if (!isObject(value)) { + return value; + } // Also return a merge proxy for nested objects + + + if (!value[IS_PROXY]) { + var keyPath = [].concat(_toConsumableArray(pathSegments), [key]); + value = createProxy(context, value, resolveContext, keyPath); + Reflect.set(target, key, value); + } + + return value; + }, + set: function set(target, key, value) { + var success = Reflect.set(target, key, value); // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) + + if (success) { + var isArrayItem = isArray(target); + var hasArrayParent = false; + var proxies = context.sources, + active = context.active; + var activeSegmentKey; + var index = 0; + + var _iterator = _createForOfIteratorHelper$2(pathSegments), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var segment = _step.value; + proxies = pluck(proxies, segment); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + break; + } + + if (isArray(active)) { + hasArrayParent = true; + } + + active = active[segment]; + index++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + if (hasArrayParent) { + // TODO: fix that we dont have to recompute the full merged object + // we should only have to recompute the branch that has changed + // but there is an issue here with supporting both arrays of strings + // as collections (parent vs parent of parent we need to trigger the + // update from) + recompute(context); + return success; + } else if (isPlainObject(value)) { + // if an object was assigned to this key make sure to recompute all + // of its individual properies + recompute(context, pathSegments); + return success; + } + + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); // Ensure to clone if value is an object, cause sources is an array of + // the sourceProxies and not the sources so we could trigger an endless loop when + // updating a prop on an obj as the prop on the active object refers to + // a prop on a proxy + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) + + + return success; + }, + deleteProperty: function deleteProperty(target, key) { + var success = Reflect.deleteProperty(target, key); // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) + + if (success) { + var isArrayItem = isArray(target); + var activeSegmentKey; + var proxies = context.sources; + var active = context.active; + var index = 0; + + var _iterator2 = _createForOfIteratorHelper$2(pathSegments), + _step2; + + try { + var _loop = function _loop() { + var segment = _step2.value; + // @ts-ignore + proxies = proxies.map(function (proxy) { + return proxy && proxy[segment]; + }); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + return "break"; + } + + active = active[segment]; + index++; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret = _loop(); + + if (_ret === "break") break; + } // Check if the key still exists in one of the sourceProxies, + // if so resolve the new value, if not remove the key + + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + if (proxies.some(function (proxy) { + return proxy && key in proxy; + })) { + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', resolved) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } else { + delete active[key]; + } + } + + return success; + } + }; }; -const cachedElements = {}; -function renderMeta(context, key, data, config) { - // console.info('renderMeta', key, data, config) - if ('attributesFor' in config) { - return renderAttributes(context, key, data, config); - } - if ('group' in config) { - return renderGroup(context, key, data, config); - } - return renderTag(context, key, data, config); -} -function renderGroup(context, key, data, config) { - // console.info('renderGroup', key, data, config) - if (isArray(data)) { - if (("development" !== 'production')) { - // eslint-disable-next-line no-console - console.warn('Specifying an array for group properties isnt supported'); - } - // config.attributes = getConfigKey([key, config.tag], 'attributes', config) - return []; - } - return Object.keys(data) - .map((childKey) => { - const groupConfig = { - group: key, - data - }; - if (config.namespaced) { - groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; - } - else if (config.namespacedAttribute) { - const namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; - groupConfig.fullName = `${namespace}:${childKey}`; - groupConfig.slotName = `${namespace}(${childKey})`; - } - return renderTag(context, key, data[childKey], config, groupConfig); - }) - .filter(Boolean) - .flat(); -} -function renderTag(context, key, data, config = {}, groupConfig) { - // console.info('renderTag', key, data, config, groupConfig) - const contentAttributes = ['content', 'json', 'rawContent']; - const getTagConfig = (key) => getTagConfigItem([tag, config.tag], key); - if (isArray(data)) { - return data - .map((child) => { - return renderTag(context, key, child, config, groupConfig); - }) - .filter(Boolean) - .flat(); - } - const { tag = config.tag || key } = data; - let content = ''; - let hasChilds = false; - let isRaw = false; - if (isString(data)) { - content = data; - } - else if (data.children && isArray(data.children)) { - hasChilds = true; - content = data.children.map((child) => { - const data = renderTag(context, key, child, config, groupConfig); - if (isArray(data)) { - return data.map(({ vnode }) => vnode); - } - return data && data.vnode; - }); - } - else { - let i = 0; - for (const contentAttribute of contentAttributes) { - if (!content && data[contentAttribute]) { - if (i === 1) { - content = JSON.stringify(data[contentAttribute]); - } - else { - content = data[contentAttribute]; - } - isRaw = i > 1; - break; - } - i++; - } - } - const fullName = (groupConfig && groupConfig.fullName) || key; - const slotName = (groupConfig && groupConfig.slotName) || key; - let { attrs: attributes } = data; - if (!attributes && typeof data === 'object') { - attributes = { ...data }; - delete attributes.tag; - delete attributes.children; - delete attributes.to; - // cleanup all content attributes - for (const attr of contentAttributes) { - delete attributes[attr]; - } - } - else if (!attributes) { - attributes = {}; - } - if (hasChilds) { - content = getSlotContent(context, slotName, content, data); - } - else { - const contentAsAttribute = !!getTagConfig('contentAsAttribute'); - let { valueAttribute } = config; - if (!valueAttribute && contentAsAttribute) { - const [tagAttribute] = getTagConfig('attributes'); - valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; - } - if (!valueAttribute) { - content = getSlotContent(context, slotName, content, data); - } - else { - const { nameless } = config; - if (!nameless) { - const keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); - if (keyAttribute) { - attributes[keyAttribute] = fullName; - } - } - attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); - content = ''; - } - } - const finalTag = groupConfig && groupConfig.tagNamespace - ? `${groupConfig.tagNamespace}:${tag}` - : tag; - if (finalTag === 'title' && !context.isSSR) { - document.title = content; - return; - } - // console.info('FINAL TAG', finalTag) - // console.log(' ATTRIBUTES', attributes) - // console.log(' CONTENT', content) - // console.log(data, attributes, config) - if (isRaw && content) { - attributes.innerHTML = content; - } - // Ignore empty string content - const vnode = h(finalTag, attributes, content || undefined); - return { - to: data.to, - vnode - }; -} -function renderAttributes(context, key, data, config) { - // console.info('renderAttributes', key, data, config) - const { attributesFor } = config; - if (!attributesFor || !data) { - return; - } - if (context.isSSR) { - // render attributes in a placeholder vnode so Vue - // will render the string for us - return { - to: '', - vnode: h(`ssr-${attributesFor}`, data) - }; - } - if (!cachedElements[attributesFor]) { - const [el, el2] = Array.from(document.querySelectorAll(attributesFor)); - if (("development" !== 'production') && !el) { - // eslint-disable-next-line no-console - console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); - return; - } - if (("development" !== 'production') && el2) { - // eslint-disable-next-line no-console - console.warn('Found multiple elements for selector', attributesFor); - } - cachedElements[attributesFor] = { - el, - attrs: [] - }; - } - const { el, attrs } = cachedElements[attributesFor]; - for (const attr in data) { - let content = getSlotContent(context, `${key}(${attr})`, data[attr], data); - if (isArray(content)) { - content = content.join(','); - } - el.setAttribute(attr, content || ''); - if (!attrs.includes(attr)) { - attrs.push(attr); - } - } - const attrsToRemove = attrs.filter(attr => !data[attr]); - for (const attr of attrsToRemove) { - el.removeAttribute(attr); - } -} -function getSlotContent({ metainfo, slots }, slotName, content, groupConfig) { - const slot = slots && slots[slotName]; - if (!slot || !isFunction(slot)) { - return content; - } - const slotScopeProps = { - content, - metainfo - }; - if (groupConfig && groupConfig.group) { - const { group, data } = groupConfig; - slotScopeProps[group] = data; - } - const slotContent = slot(slotScopeProps); - if (slotContent && slotContent.length) { - const { children } = slotContent[0]; - return children ? children.toString() : ''; - } - return content; +var createMergedObject = function createMergedObject(resolve, active) { + var sources = []; + var context = { + active: active, + resolve: resolve, + sources: sources + }; + + var compute = function compute() { + return recompute(context); + }; + + return { + context: context, + compute: compute, + addSource: function addSource(source, resolveContext) { + var recompute = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var proxy = createProxy(context, source, resolveContext || {}); + + if (recompute) { + compute(); + } + + return proxy; + }, + delSource: function delSource(sourceOrProxy) { + var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var index = sources.findIndex(function (source) { + return source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy; + }); + + if (index > -1) { + sources.splice(index, 1); + + if (recompute) { + compute(); + } + + return true; + } + + return false; + } + }; +}; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(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$1(o, minLen); } + +function _arrayLikeToArray$1(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; } +var cachedElements = {}; +function renderMeta(context, key, data, config) { + // console.info('renderMeta', key, data, config) + if ('attributesFor' in config) { + return renderAttributes(context, key, data, config); + } + + if ('group' in config) { + return renderGroup(context, key, data, config); + } + + return renderTag(context, key, data, config); +} +function renderGroup(context, key, data, config) { + // console.info('renderGroup', key, data, config) + if (isArray(data)) { + if ("development" !== 'production') { + // eslint-disable-next-line no-console + console.warn('Specifying an array for group properties isnt supported'); + } // config.attributes = getConfigKey([key, config.tag], 'attributes', config) + + + return []; + } + + return Object.keys(data).map(function (childKey) { + var groupConfig = { + group: key, + data: data + }; + + if (config.namespaced) { + groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; + } else if (config.namespacedAttribute) { + var namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; + groupConfig.fullName = "".concat(namespace, ":").concat(childKey); + groupConfig.slotName = "".concat(namespace, "(").concat(childKey, ")"); + } + + return renderTag(context, key, data[childKey], config, groupConfig); + }).filter(Boolean).flat(); } +function renderTag(context, key, data) { + var config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var groupConfig = arguments.length > 4 ? arguments[4] : undefined; + // console.info('renderTag', key, data, config, groupConfig) + var contentAttributes = ['content', 'json', 'rawContent']; -const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; -const PolySymbol = (name) => -// vm = vue meta -hasSymbol - ? Symbol(("development" !== 'production') ? '[vue-meta]: ' + name : name) - : (("development" !== 'production') ? '[vue-meta]: ' : '_vm_') + name; -const metaActiveKey = /*#__PURE__*/ PolySymbol(("development" !== 'production') ? 'meta_active' : 'ma'); + var getTagConfig = function getTagConfig(key) { + return getTagConfigItem([tag, config.tag], key); + }; + + if (isArray(data)) { + return data.map(function (child) { + return renderTag(context, key, child, config, groupConfig); + }).filter(Boolean).flat(); + } + + var _data$tag = data.tag, + tag = _data$tag === void 0 ? config.tag || key : _data$tag; + var content = ''; + var hasChilds = false; + var isRaw = false; + + if (isString(data)) { + content = data; + } else if (data.children && isArray(data.children)) { + hasChilds = true; + content = data.children.map(function (child) { + var data = renderTag(context, key, child, config, groupConfig); + + if (isArray(data)) { + return data.map(function (_ref) { + var vnode = _ref.vnode; + return vnode; + }); + } + + return data && data.vnode; + }); + } else { + var i = 0; + + var _iterator = _createForOfIteratorHelper$1(contentAttributes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var contentAttribute = _step.value; + + if (!content && data[contentAttribute]) { + if (i === 1) { + content = JSON.stringify(data[contentAttribute]); + } else { + content = data[contentAttribute]; + } + + isRaw = i > 1; + break; + } + + i++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + var fullName = groupConfig && groupConfig.fullName || key; + var slotName = groupConfig && groupConfig.slotName || key; + var attributes = data.attrs; + + if (!attributes && _typeof(data) === 'object') { + attributes = _objectSpread({}, data); + delete attributes.tag; + delete attributes.children; + delete attributes.to; // cleanup all content attributes + + var _iterator2 = _createForOfIteratorHelper$1(contentAttributes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var attr = _step2.value; + delete attributes[attr]; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } else if (!attributes) { + attributes = {}; + } + + if (hasChilds) { + content = getSlotContent(context, slotName, content, data); + } else { + var contentAsAttribute = !!getTagConfig('contentAsAttribute'); + var valueAttribute = config.valueAttribute; + + if (!valueAttribute && contentAsAttribute) { + var _getTagConfig = getTagConfig('attributes'), + _getTagConfig2 = _slicedToArray(_getTagConfig, 1), + tagAttribute = _getTagConfig2[0]; + + valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; + } + + if (!valueAttribute) { + content = getSlotContent(context, slotName, content, data); + } else { + var nameless = config.nameless; + + if (!nameless) { + var keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); + + if (keyAttribute) { + attributes[keyAttribute] = fullName; + } + } + + attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); + content = ''; + } + } + + var finalTag = groupConfig && groupConfig.tagNamespace ? "".concat(groupConfig.tagNamespace, ":").concat(tag) : tag; + + if (finalTag === 'title' && !context.isSSR) { + document.title = content; + return; + } // console.info('FINAL TAG', finalTag) + // console.log(' ATTRIBUTES', attributes) + // console.log(' CONTENT', content) + // console.log(data, attributes, config) + + + if (isRaw && content) { + attributes.innerHTML = content; + } // Ignore empty string content + + + var vnode = h(finalTag, attributes, content || undefined); + return { + to: data.to, + vnode: vnode + }; +} +function renderAttributes(context, key, data, config) { + // console.info('renderAttributes', key, data, config) + var attributesFor = config.attributesFor; + + if (!attributesFor || !data) { + return; + } + + if (context.isSSR) { + // render attributes in a placeholder vnode so Vue + // will render the string for us + return { + to: '', + vnode: h("ssr-".concat(attributesFor), data) + }; + } + + if (!cachedElements[attributesFor]) { + var _Array$from = Array.from(document.querySelectorAll(attributesFor)), + _Array$from2 = _slicedToArray(_Array$from, 2), + _el = _Array$from2[0], + el2 = _Array$from2[1]; + + if ("development" !== 'production' && !_el) { + // eslint-disable-next-line no-console + console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); + return; + } + + if ("development" !== 'production' && el2) { + // eslint-disable-next-line no-console + console.warn('Found multiple elements for selector', attributesFor); + } + + cachedElements[attributesFor] = { + el: _el, + attrs: [] + }; + } + + var _cachedElements$attri = cachedElements[attributesFor], + el = _cachedElements$attri.el, + attrs = _cachedElements$attri.attrs; + + for (var attr in data) { + var content = getSlotContent(context, "".concat(key, "(").concat(attr, ")"), data[attr], data); + + if (isArray(content)) { + content = content.join(','); + } + + el.setAttribute(attr, content || ''); + + if (!attrs.includes(attr)) { + attrs.push(attr); + } + } + + var attrsToRemove = attrs.filter(function (attr) { + return !data[attr]; + }); + + var _iterator3 = _createForOfIteratorHelper$1(attrsToRemove), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _attr = _step3.value; + el.removeAttribute(_attr); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } +} +function getSlotContent(_ref2, slotName, content, groupConfig) { + var metainfo = _ref2.metainfo, + slots = _ref2.slots; + var slot = slots && slots[slotName]; + + if (!slot || !isFunction(slot)) { + return content; + } + + var slotScopeProps = { + content: content, + metainfo: metainfo + }; + + if (groupConfig && groupConfig.group) { + var group = groupConfig.group, + data = groupConfig.data; + slotScopeProps[group] = data; + } + + var slotContent = slot(slotScopeProps); + + if (slotContent && slotContent.length) { + var children = slotContent[0].children; + return children ? children.toString() : ''; + } + + return content; +} + +var hasSymbol = typeof Symbol === 'function' && _typeof(Symbol.toStringTag) === 'symbol'; +var PolySymbol = function PolySymbol(name) { + return (// vm = vue meta + hasSymbol ? Symbol("development" !== 'production' ? '[vue-meta]: ' + name : name) : ("development" !== 'production' ? '[vue-meta]: ' : '_vm_') + name + ); +}; +var metaActiveKey = /*#__PURE__*/PolySymbol("development" !== 'production' ? 'meta_active' : 'ma'); /** * Apply the differences between newSource & oldSource to target - */ -function applyDifference(target, newSource, oldSource) { - for (const key in newSource) { - if (!(key in oldSource)) { - target[key] = newSource[key]; - continue; - } - if (isObject(target[key])) { - applyDifference(target[key], newSource[key], oldSource[key]); - continue; - } - if (newSource[key] !== oldSource[key]) { - target[key] = newSource[key]; - } - } - for (const key in oldSource) { - if (!newSource || !(key in newSource)) { - delete target[key]; - } - } + */ + +function applyDifference(target, newSource, oldSource) { + for (var key in newSource) { + if (!(key in oldSource)) { + target[key] = newSource[key]; + continue; + } + + if (isObject(target[key])) { + applyDifference(target[key], newSource[key], oldSource[key]); + continue; + } + + if (newSource[key] !== oldSource[key]) { + target[key] = newSource[key]; + } + } + + for (var _key in oldSource) { + if (!newSource || !(_key in newSource)) { + delete target[_key]; + } + } } -function getCurrentManager(vm) { - if (!vm) { - vm = getCurrentInstance() || undefined; - } - if (!vm) { - return undefined; - } - return vm.appContext.config.globalProperties.$metaManager; -} -function useMeta(source, manager) { - const vm = getCurrentInstance() || undefined; - if (!manager && vm) { - manager = getCurrentManager(vm); - } - if (!manager) { - throw new Error('No manager or current instance'); - } - if (isProxy(source)) { - watch(source, (newSource, oldSource) => { - applyDifference(metaProxy.meta, newSource, oldSource); - }); - source = source.value; - } - const metaProxy = manager.addMeta(source, vm); - return metaProxy; -} -function useActiveMeta() { - return inject(metaActiveKey); +function getCurrentManager(vm) { + if (!vm) { + vm = getCurrentInstance() || undefined; + } + + if (!vm) { + return undefined; + } + + return vm.appContext.config.globalProperties.$metaManager; } +function useMeta(source, manager) { + var vm = getCurrentInstance() || undefined; + + if (!manager && vm) { + manager = getCurrentManager(vm); + } + + if (!manager) { + throw new Error('No manager or current instance'); + } -const MetainfoImpl = defineComponent({ - name: 'Metainfo', - inheritAttrs: false, - setup(_, { slots }) { - return () => { - const manager = getCurrentManager(); - if (!manager) { - return; - } - return manager.render({ slots }); - }; - } -}); -const Metainfo = MetainfoImpl; - -const ssrAttribute = 'data-vm-ssr'; -function addVnode(isSSR, teleports, to, vnodes) { - const nodes = (isArray(vnodes) ? vnodes : [vnodes]); - if (!isSSR) { - // Comments shouldnt have any use on the client as they are not reactive anyway - nodes.forEach((vnode, idx) => { - if (vnode.type === Comment) { - nodes.splice(idx, 1); - } - }); - // only add ssrAttribute's for real meta tags - } - else if (!to.endsWith('Attrs')) { - nodes.forEach((vnode) => { - if (!vnode.props) { - vnode.props = {}; - } - vnode.props[ssrAttribute] = true; - }); - } - if (!teleports[to]) { - teleports[to] = []; - } - teleports[to].push(...nodes); -} -const createMetaManager = (isSSR = false, config, resolver) => MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); -class MetaManager { - isSSR = false; - config; - target; - resolver; - ssrCleanedUp = false; - constructor(isSSR, config, target, resolver) { - this.isSSR = isSSR; - this.config = config; - this.target = target; - if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { - this.resolver = resolver; - } - } - static create = (isSSR, config, resolver) => { - const resolve = (options, contexts, active, key, pathSegments) => { - if (isFunction(resolver)) { - return resolver(options, contexts, active, key, pathSegments); - } - return resolver.resolve(options, contexts, active, key, pathSegments); - }; - const active = reactive({}); - const mergedObject = createMergedObject(resolve, active); - // TODO: validate resolver - const manager = new MetaManager(isSSR, config, mergedObject, resolver); - return manager; - }; - install(app) { - app.component('Metainfo', Metainfo); - app.config.globalProperties.$metaManager = this; - app.provide(metaActiveKey, this.target.context.active); - } - addMeta(metadata, vm) { - if (!vm) { - vm = getCurrentInstance() || undefined; - } - const metaGuards = ({ - removed: [] - }); - const resolveContext = { vm }; - const { resolver } = this; - if (resolver && resolver.setup) { - resolver.setup(resolveContext); - } - // TODO: optimize initial compute (once) - const meta = this.target.addSource(metadata, resolveContext, true); - const onRemoved = (removeGuard) => metaGuards.removed.push(removeGuard); - const unmount = (ignoreGuards) => this.unmount(!!ignoreGuards, meta, metaGuards, vm); - if (vm) { - onUnmounted(unmount); - } - return { - meta, - onRemoved, - unmount - }; - } - unmount(ignoreGuards, meta, metaGuards, vm) { - if (vm) { - const { $el } = vm.proxy; - // Wait for element to be removed from DOM - if ($el && $el.offsetParent) { - let observer = new MutationObserver((records) => { - for (const { removedNodes } of records) { - if (!removedNodes) { - continue; - } - removedNodes.forEach((el) => { - if (el === $el && observer) { - observer.disconnect(); - observer = undefined; - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - }); - } - }); - observer.observe($el.parentNode, { childList: true }); - return; - } - } - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - async reallyUnmount(ignoreGuards, meta, metaGuards) { - this.target.delSource(meta); - if (!ignoreGuards && metaGuards) { - await Promise.all(metaGuards.removed.map(removeGuard => removeGuard())); - } - } - render({ slots } = {}) { - const active = this.target.context.active; - // TODO: clean this method - const { isSSR } = this; - // cleanup ssr tags if not yet done - if (!isSSR && !this.ssrCleanedUp) { - this.ssrCleanedUp = true; - const cleanUpSSR = () => { - const ssrTags = document.querySelectorAll(`[${ssrAttribute}]`); - if (ssrTags && ssrTags.length) { - ssrTags.forEach(el => el.parentNode && el.parentNode.removeChild(el)); - } - }; - if (document.readyState === 'loading') { - // Listen for DOM loaded because tags in the body couldnt - // have loaded yet once the manager does it first render - // (preferable there should only be one meta render on hydration) - window.addEventListener('DOMContentLoaded', cleanUpSSR, { once: true }); - } - else { - cleanUpSSR(); - } - } - const teleports = {}; - for (const key in active) { - const config = this.config[key] || {}; - let renderedNodes = renderMeta({ isSSR, metainfo: active, slots }, key, active[key], config); - if (!renderedNodes) { - continue; - } - if (!isArray(renderedNodes)) { - renderedNodes = [renderedNodes]; - } - let defaultTo = key !== 'base' && active[key].to; - if (!defaultTo && 'to' in config) { - defaultTo = config.to; - } - if (!defaultTo && 'attributesFor' in config) { - defaultTo = key; - } - for (const { to, vnode } of renderedNodes) { - addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); - } - } - if (slots) { - for (const slotName in slots) { - const tagName = slotName === 'default' ? 'head' : slotName; - // Only teleport the contents of head/body slots - if (tagName !== 'head' && tagName !== 'body') { - continue; - } - const slot = slots[slotName]; - if (isFunction(slot)) { - addVnode(this.isSSR, teleports, tagName, slot({ metainfo: active })); - } - } - } - return Object.keys(teleports).map((to) => { - const teleport = teleports[to]; - return h(Teleport, { to }, teleport); - }); - } + if (isProxy(source)) { + watch(source, function (newSource, oldSource) { + applyDifference(metaProxy.meta, newSource, oldSource); + }); + source = source.value; + } + + var metaProxy = manager.addMeta(source, vm); + return metaProxy; +} +function useActiveMeta() { + return inject(metaActiveKey); } -const defaultOptions = { - keyName: 'metaInfo' -}; -const createMixin = options => ({ - created() { - const instance = getCurrentInstance(); - if (!instance?.type || !(options.keyName in instance.type)) { - return; - } - const metaInfo = instance.type[options.keyName]; - if (isFunction(metaInfo)) { - const computedMetaInfo = computed(metaInfo.bind(this)); - useMeta(computedMetaInfo); - } - else { - useMeta(metaInfo); - } - } -}); -const install = (app, _options = {}) => { - const options = Object.assign({}, defaultOptions, _options); - app.mixin(createMixin(options)); +var MetainfoImpl = defineComponent({ + name: 'Metainfo', + inheritAttrs: false, + setup: function setup(_, _ref) { + var slots = _ref.slots; + return function () { + var manager = getCurrentManager(); + + if (!manager) { + return; + } + + return manager.render({ + slots: slots + }); + }; + } +}); +var Metainfo = MetainfoImpl; + +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +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; } +var ssrAttribute = 'data-vm-ssr'; +function addVnode(isSSR, teleports, to, vnodes) { + var _teleports$to; + + var nodes = isArray(vnodes) ? vnodes : [vnodes]; + + if (!isSSR) { + // Comments shouldnt have any use on the client as they are not reactive anyway + nodes.forEach(function (vnode, idx) { + if (vnode.type === Comment) { + nodes.splice(idx, 1); + } + }); // only add ssrAttribute's for real meta tags + } else if (!to.endsWith('Attrs')) { + nodes.forEach(function (vnode) { + if (!vnode.props) { + vnode.props = {}; + } + + vnode.props[ssrAttribute] = true; + }); + } + + if (!teleports[to]) { + teleports[to] = []; + } + + (_teleports$to = teleports[to]).push.apply(_teleports$to, _toConsumableArray(nodes)); +} +var createMetaManager = function createMetaManager() { + var isSSR = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var config = arguments.length > 1 ? arguments[1] : undefined; + var resolver = arguments.length > 2 ? arguments[2] : undefined; + return MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); +}; +var MetaManager = /*#__PURE__*/function () { + function MetaManager(isSSR, config, target, resolver) { + _classCallCheck(this, MetaManager); + + _defineProperty(this, "isSSR", false); + + _defineProperty(this, "config", void 0); + + _defineProperty(this, "target", void 0); + + _defineProperty(this, "resolver", void 0); + + _defineProperty(this, "ssrCleanedUp", false); + + this.isSSR = isSSR; + this.config = config; + this.target = target; + + if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { + this.resolver = resolver; + } + } + + _createClass(MetaManager, [{ + key: "install", + value: function install(app) { + app.component('Metainfo', Metainfo); + app.config.globalProperties.$metaManager = this; + app.provide(metaActiveKey, this.target.context.active); + } + }, { + key: "addMeta", + value: function addMeta(metadata, vm) { + var _this = this; + + if (!vm) { + vm = getCurrentInstance() || undefined; + } + + var metaGuards = { + removed: [] + }; + var resolveContext = { + vm: vm + }; + var resolver = this.resolver; + + if (resolver && resolver.setup) { + resolver.setup(resolveContext); + } // TODO: optimize initial compute (once) + + + var meta = this.target.addSource(metadata, resolveContext, true); + + var onRemoved = function onRemoved(removeGuard) { + return metaGuards.removed.push(removeGuard); + }; + + var unmount = function unmount(ignoreGuards) { + return _this.unmount(!!ignoreGuards, meta, metaGuards, vm); + }; + + if (vm) { + onUnmounted(unmount); + } + + return { + meta: meta, + onRemoved: onRemoved, + unmount: unmount + }; + } + }, { + key: "unmount", + value: function unmount(ignoreGuards, meta, metaGuards, vm) { + var _this2 = this; + + if (vm) { + var $el = vm.proxy.$el; // Wait for element to be removed from DOM + + if ($el && $el.offsetParent) { + var observer = new MutationObserver(function (records) { + var _iterator = _createForOfIteratorHelper(records), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var removedNodes = _step.value.removedNodes; + + if (!removedNodes) { + continue; + } + + removedNodes.forEach(function (el) { + if (el === $el && observer) { + observer.disconnect(); + observer = undefined; + + _this2.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }); + observer.observe($el.parentNode, { + childList: true + }); + return; + } + } + + this.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }, { + key: "reallyUnmount", + value: function () { + var _reallyUnmount = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ignoreGuards, meta, metaGuards) { + return _regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + this.target.delSource(meta); + + if (!(!ignoreGuards && metaGuards)) { + _context.next = 4; + break; + } + + _context.next = 4; + return Promise.all(metaGuards.removed.map(function (removeGuard) { + return removeGuard(); + })); + + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function reallyUnmount(_x, _x2, _x3) { + return _reallyUnmount.apply(this, arguments); + } + + return reallyUnmount; + }() + }, { + key: "render", + value: function render() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + slots = _ref.slots; + + var active = this.target.context.active; // TODO: clean this method + + var isSSR = this.isSSR; // cleanup ssr tags if not yet done + + if (!isSSR && !this.ssrCleanedUp) { + this.ssrCleanedUp = true; + + var cleanUpSSR = function cleanUpSSR() { + var ssrTags = document.querySelectorAll("[".concat(ssrAttribute, "]")); + + if (ssrTags && ssrTags.length) { + ssrTags.forEach(function (el) { + return el.parentNode && el.parentNode.removeChild(el); + }); + } + }; + + if (document.readyState === 'loading') { + // Listen for DOM loaded because tags in the body couldnt + // have loaded yet once the manager does it first render + // (preferable there should only be one meta render on hydration) + window.addEventListener('DOMContentLoaded', cleanUpSSR, { + once: true + }); + } else { + cleanUpSSR(); + } + } + + var teleports = {}; + + for (var key in active) { + var config = this.config[key] || {}; + var renderedNodes = renderMeta({ + isSSR: isSSR, + metainfo: active, + slots: slots + }, key, active[key], config); + + if (!renderedNodes) { + continue; + } + + if (!isArray(renderedNodes)) { + renderedNodes = [renderedNodes]; + } + + var defaultTo = key !== 'base' && active[key].to; + + if (!defaultTo && 'to' in config) { + defaultTo = config.to; + } + + if (!defaultTo && 'attributesFor' in config) { + defaultTo = key; + } + + var _iterator2 = _createForOfIteratorHelper(renderedNodes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _step2.value, + to = _step2$value.to, + vnode = _step2$value.vnode; + addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + if (slots) { + for (var slotName in slots) { + var tagName = slotName === 'default' ? 'head' : slotName; // Only teleport the contents of head/body slots + + if (tagName !== 'head' && tagName !== 'body') { + continue; + } + + var slot = slots[slotName]; + + if (isFunction(slot)) { + addVnode(this.isSSR, teleports, tagName, slot({ + metainfo: active + })); + } + } + } + + return Object.keys(teleports).map(function (to) { + var teleport = teleports[to]; + return h(Teleport, { + to: to + }, teleport); + }); + } + }]); + + return MetaManager; +}(); + +_defineProperty(MetaManager, "create", function (isSSR, config, resolver) { + var resolve = function resolve(options, contexts, active, key, pathSegments) { + if (isFunction(resolver)) { + return resolver(options, contexts, active, key, pathSegments); + } + + return resolver.resolve(options, contexts, active, key, pathSegments); + }; + + var active = reactive({}); + var mergedObject = createMergedObject(resolve, active); // TODO: validate resolver + + var manager = new MetaManager(isSSR, config, mergedObject, resolver); + return manager; +}); + +var defaultOptions = { + keyName: 'metaInfo' +}; +var createMixin = function createMixin(options) { + return { + created: function created() { + var instance = getCurrentInstance(); + + if (!(instance !== null && instance !== void 0 && instance.type) || !(options.keyName in instance.type)) { + return; + } + + var metaInfo = instance.type[options.keyName]; + + if (isFunction(metaInfo)) { + var computedMetaInfo = computed(metaInfo.bind(this)); + useMeta(computedMetaInfo); + } else { + useMeta(metaInfo); + } + } + }; +}; +var install = function install(app) { + var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var options = Object.assign({}, defaultOptions, _options); + app.mixin(createMixin(options)); }; export { createMetaManager, defaultResolver as deepestResolver, defaultConfig, getCurrentManager, install as plugin, resolveOption, useActiveMeta, useMeta }; diff --git a/dist/vue-meta.global.js b/dist/vue-meta.global.js index 39000b0b..6b50a29f 100644 --- a/dist/vue-meta.global.js +++ b/dist/vue-meta.global.js @@ -6,43 +6,64 @@ * @license MIT */ -var VueMeta = (function (exports, vue) { +var VueMeta = (function (exports, _asyncToGenerator, _classCallCheck, _createClass, _defineProperty, _toConsumableArray, _regeneratorRuntime, vue, _typeof, _slicedToArray) { 'use strict'; - const resolveOption = (predicament, initialValue) => (options, contexts) => { - let resolvedIndex = -1; - contexts.reduce((acc, context, index) => { - const retval = predicament(acc, context); - if (retval !== acc) { - resolvedIndex = index; - return retval; - } - return acc; - }, initialValue); - if (resolvedIndex > -1) { - return options[resolvedIndex]; - } + function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } + + var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator); + var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck); + var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass); + var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); + var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); + var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime); + var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof); + var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); + + var resolveOption = function resolveOption(predicament, initialValue) { + return function (options, contexts) { + var resolvedIndex = -1; + contexts.reduce(function (acc, context, index) { + var retval = predicament(acc, context); + + if (retval !== acc) { + resolvedIndex = index; + return retval; + } + + return acc; + }, initialValue); + + if (resolvedIndex > -1) { + return options[resolvedIndex]; + } + }; + }; + + var setup = function setup(context) { + var depth = 0; + + if (context.vm) { + var vm = context.vm; + + do { + if (vm.parent) { + depth++; + vm = vm.parent; + } + } while (vm && vm.parent && vm !== vm.root); + } + + context.depth = depth; }; + var resolve = resolveOption(function (currentValue, context) { + var depth = context.depth; + + if (!currentValue || depth > currentValue) { + return depth; + } - const setup = (context) => { - let depth = 0; - if (context.vm) { - let { vm } = context; - do { - if (vm.parent) { - depth++; - vm = vm.parent; - } - } while (vm && vm.parent && vm !== vm.root); - } - context.depth = depth; - }; - const resolve = resolveOption((currentValue, context) => { - const { depth } = context; - if (!currentValue || depth > currentValue) { - return depth; - } - return currentValue; + return currentValue; }); var defaultResolver = /*#__PURE__*/Object.freeze({ @@ -51,105 +72,98 @@ var VueMeta = (function (exports, vue) { resolve: resolve }); - const defaultConfig = { - body: { - tag: 'script', - to: 'body' - }, - base: { - valueAttribute: 'href' - }, - charset: { - tag: 'meta', - nameless: true, - valueAttribute: 'charset' - }, - description: { - tag: 'meta' - }, - og: { - group: true, - namespacedAttribute: true, - tag: 'meta', - keyAttribute: 'property' - }, - twitter: { - group: true, - namespacedAttribute: true, - tag: 'meta' - }, - htmlAttrs: { - attributesFor: 'html' - }, - headAttrs: { - attributesFor: 'head' - }, - bodyAttrs: { - attributesFor: 'body' - } + var defaultConfig = { + body: { + tag: 'script', + to: 'body' + }, + base: { + valueAttribute: 'href' + }, + charset: { + tag: 'meta', + nameless: true, + valueAttribute: 'charset' + }, + description: { + tag: 'meta' + }, + og: { + group: true, + namespacedAttribute: true, + tag: 'meta', + keyAttribute: 'property' + }, + twitter: { + group: true, + namespacedAttribute: true, + tag: 'meta' + }, + htmlAttrs: { + attributesFor: 'html' + }, + headAttrs: { + attributesFor: 'head' + }, + bodyAttrs: { + attributesFor: 'body' + } }; /* * This is a fixed config for real HTML tags - */ - const tags = { - title: { - attributes: false - }, - base: { - contentAsAttribute: true, - attributes: ['href', 'target'] - }, - meta: { - contentAsAttribute: true, - keyAttribute: 'name', - attributes: ['content', 'name', 'http-equiv', 'charset'] - }, - link: { - contentAsAttribute: true, - attributes: [ - 'href', - 'crossorigin', - 'rel', - 'media', - 'integrity', - 'hreflang', - 'type', - 'referrerpolicy', - 'sizes', - 'imagesrcset', - 'imagesizes', - 'as', - 'color' - ] - }, - style: { - attributes: ['media'] - }, - script: { - attributes: [ - 'src', - 'type', - 'nomodule', - 'async', - 'defer', - 'crossorigin', - 'integrity', - 'referrerpolicy' - ] - }, - noscript: { - attributes: false - } + */ + var tags = { + title: { + attributes: false + }, + base: { + contentAsAttribute: true, + attributes: ['href', 'target'] + }, + meta: { + contentAsAttribute: true, + keyAttribute: 'name', + attributes: ['content', 'name', 'http-equiv', 'charset'] + }, + link: { + contentAsAttribute: true, + attributes: ['href', 'crossorigin', 'rel', 'media', 'integrity', 'hreflang', 'type', 'referrerpolicy', 'sizes', 'imagesrcset', 'imagesizes', 'as', 'color'] + }, + style: { + attributes: ['media'] + }, + script: { + attributes: ['src', 'type', 'nomodule', 'async', 'defer', 'crossorigin', 'integrity', 'referrerpolicy'] + }, + noscript: { + attributes: false + } }; - function getTagConfigItem(tagOrName, key) { - for (const name of tagOrName) { - const tag = tags[name]; - if (name && tag) { - return tag[key]; - } - } + function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(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$5(o, minLen); } + + function _arrayLikeToArray$5(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 getTagConfigItem(tagOrName, key) { + var _iterator = _createForOfIteratorHelper$5(tagOrName), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var name = _step.value; + var tag = tags[name]; + + if (name && tag) { + return tag[key]; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } } /** @@ -159,6 +173,7 @@ var VueMeta = (function (exports, vue) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ + Object.freeze({}) ; Object.freeze([]) ; @@ -170,805 +185,1275 @@ var VueMeta = (function (exports, vue) { const toTypeString = (value) => objectToString.call(value); const isPlainObject = (val) => toTypeString(val) === '[object Object]'; - // https://github.com/microsoft/TypeScript/issues/1863 - const IS_PROXY = Symbol('kIsProxy'); - const PROXY_SOURCES = Symbol('kProxySources'); - const PROXY_TARGET = Symbol('kProxyTarget'); - const RESOLVE_CONTEXT = Symbol('kResolveContext'); - - // See: https://github.com/vuejs/vue-next/blob/08b4e8815da4e8911058ccbab986bea6365c3352/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts - function clone(v) { - if (isArray(v)) { - return v.map(clone); - } - if (isObject(v)) { - const res = {}; - for (const key in v) { - // never clone the context - if (key === 'context') { - res[key] = v[key]; - } - else { - res[key] = clone(v[key]); - } - } - return res; - } - return v; + // https://github.com/microsoft/TypeScript/issues/1863 + var IS_PROXY = Symbol('kIsProxy'); + var PROXY_SOURCES = Symbol('kProxySources'); + var PROXY_TARGET = Symbol('kProxyTarget'); + var RESOLVE_CONTEXT = Symbol('kResolveContext'); + + function clone(v) { + if (isArray(v)) { + return v.map(clone); + } + + if (isObject(v)) { + var res = {}; + + for (var key in v) { + // never clone the context + if (key === 'context') { + res[key] = v[key]; + } else { + res[key] = clone(v[key]); + } + } + + return res; + } + + return v; } - const pluck = (collection, key, callback) => { - const plucked = []; - for (const row of collection) { - if (row && key in row) { - plucked.push(row[key]); - if (callback) { - callback(row); - } - } - } - return plucked; + function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(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$4(o, minLen); } + + function _arrayLikeToArray$4(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; } + + var pluck = function pluck(collection, key, callback) { + var plucked = []; + + var _iterator = _createForOfIteratorHelper$4(collection), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var row = _step.value; + + if (row && key in row) { + plucked.push(row[key]); + + if (callback) { + callback(row); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return plucked; + }; + + var debugFn = function debugFn(logFn) { + var setChildFns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fn = function fn() { + try { + throw new Error('DEBUG'); + } catch (err) { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logFn.apply(void 0, args.concat(['\n', err])); + } + }; + + if (setChildFns) { + fn.warn = debugFn(console.warn); // eslint-disable-line no-console + + fn.error = debugFn(console.error); // eslint-disable-line no-console + } + + return fn; }; + debugFn(console.log, true); // eslint-disable-line no-console + + function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(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$3(o, minLen); } + + function _arrayLikeToArray$3(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; } + var allKeys = function allKeys(source) { + var keys = source ? Object.keys(source) : []; + + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (sources) { + var _iterator = _createForOfIteratorHelper$3(sources), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _source = _step.value; + + if (!_source || !isObject(_source)) { + continue; + } - const allKeys = (source, ...sources) => { - const keys = source ? Object.keys(source) : []; - if (sources) { - for (const source of sources) { - if (!source || !isObject(source)) { - continue; - } - for (const key in source) { - if (!keys.includes(key)) { - keys.push(key); - } - } - } - } - // TODO: add check for consistent types for each key (dev only) - return keys; - }; - const recompute = (context, path = [], target, sources) => { - const setTargetAndSources = !target && !sources; - if (setTargetAndSources) { - ({ active: target, sources } = context); - if (path.length) { - for (let i = 0; i < path.length; i++) { - const seg = path[i]; - if (!target || !target[seg]) { - { - // eslint-disable-next-line no-console - console.error(`recompute: segment ${seg} not found on target`, path, target); - } - return; - } - target = target[seg]; - sources = sources.map(source => source[seg]).filter(Boolean); - } - } - } - if (!target || !sources) { - return; - } - const keys = allKeys(...sources); - // Clean up properties that dont exists anymore - const targetKeys = Object.keys(target); - for (const key of targetKeys) { - if (!keys.includes(key)) { - delete target[key]; - } - } - for (const key of keys) { - // This assumes consistent types usages for keys across sources - // @ts-ignore - let isObject = false; - for (let i = 0; i < sources.length; i++) { - const source = sources[i]; - if (source && key in source && source[key] !== undefined) { - isObject = isPlainObject(source[key]); - break; - } - } - if (isObject) { - if (!target[key]) { - target[key] = {}; - } - const keySources = []; - for (const source of sources) { - if (key in source) { - // @ts-ignore - keySources.push(source[key]); - } - } - recompute(context, [...path, key], target[key], keySources); - continue; - } - // Ensure the target is an array if source is an array and target is empty - // @ts-ignore - if (!target[key] && isArray(sources[0][key])) { - target[key] = []; - } - const keyContexts = []; - const keySources = pluck(sources, key, source => keyContexts.push(source[RESOLVE_CONTEXT])); - let resolved = context.resolve(keySources, keyContexts, target[key], key, path); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - target[key] = resolved; - } + for (var key in _source) { + if (!keys.includes(key)) { + keys.push(key); + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } // TODO: add check for consistent types for each key (dev only) + + + return keys; }; + var recompute = function recompute(context) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var target = arguments.length > 2 ? arguments[2] : undefined; + var sources = arguments.length > 3 ? arguments[3] : undefined; + var setTargetAndSources = !target && !sources; - const createProxy = (context, target, resolveContext, pathSegments = []) => { - const handler = createHandler(context, resolveContext, pathSegments); - const proxy = vue.markRaw(new Proxy(target, handler)); - if (!pathSegments.length && context.sources) { - context.sources.push(proxy); - } - return proxy; - }; - const createHandler = (context, resolveContext, pathSegments = []) => ({ - get: (target, key, receiver) => { - if (key === IS_PROXY) { - return true; - } - if (key === PROXY_SOURCES) { - return context.sources; - } - if (key === PROXY_TARGET) { - return target; - } - if (key === RESOLVE_CONTEXT) { - return resolveContext; - } - let value = Reflect.get(target, key, receiver); - if (!isObject(value)) { - return value; - } - // Also return a merge proxy for nested objects - if (!value[IS_PROXY]) { - const keyPath = [...pathSegments, key]; - value = createProxy(context, value, resolveContext, keyPath); - Reflect.set(target, key, value); - } - return value; - }, - set: (target, key, value) => { - const success = Reflect.set(target, key, value); - // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) - if (success) { - const isArrayItem = isArray(target); - let hasArrayParent = false; - let { sources: proxies, active } = context; - let activeSegmentKey; - let index = 0; - for (const segment of pathSegments) { - proxies = pluck(proxies, segment); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - if (isArray(active)) { - hasArrayParent = true; - } - active = active[segment]; - index++; - } - if (hasArrayParent) { - // TODO: fix that we dont have to recompute the full merged object - // we should only have to recompute the branch that has changed - // but there is an issue here with supporting both arrays of strings - // as collections (parent vs parent of parent we need to trigger the - // update from) - recompute(context); - return success; - } - else if (isPlainObject(value)) { - // if an object was assigned to this key make sure to recompute all - // of its individual properies - recompute(context, pathSegments); - return success; - } - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - // Ensure to clone if value is an object, cause sources is an array of - // the sourceProxies and not the sources so we could trigger an endless loop when - // updating a prop on an obj as the prop on the active object refers to - // a prop on a proxy - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) - return success; - }, - deleteProperty: (target, key) => { - const success = Reflect.deleteProperty(target, key); - // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) - if (success) { - const isArrayItem = isArray(target); - let activeSegmentKey; - let proxies = context.sources; - let active = context.active; - let index = 0; - for (const segment of pathSegments) { - // @ts-ignore - proxies = proxies.map(proxy => proxy && proxy[segment]); - if (isArrayItem && index === pathSegments.length - 1) { - activeSegmentKey = segment; - break; - } - active = active[segment]; - index++; - } - // Check if the key still exists in one of the sourceProxies, - // if so resolve the new value, if not remove the key - if (proxies.some(proxy => proxy && (key in proxy))) { - let keyContexts = []; - let keySources; - if (isArrayItem) { - keySources = proxies; - keyContexts = proxies.map(proxy => proxy[RESOLVE_CONTEXT]); - } - else { - keySources = pluck(proxies, key, proxy => keyContexts.push(proxy[RESOLVE_CONTEXT])); - } - let resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); - if (isPlainObject(resolved)) { - resolved = clone(resolved); - } - // console.log('SET VALUE', resolved) - if (isArrayItem && activeSegmentKey) { - active[activeSegmentKey] = resolved; - } - else { - active[key] = resolved; - } - } - else { - delete active[key]; - } - } - return success; - } - }); + if (setTargetAndSources) { + target = context.active; + sources = context.sources; + + if (path.length) { + var _loop = function _loop(i) { + var seg = path[i]; + + if (!target || !target[seg]) { + { + // eslint-disable-next-line no-console + console.error("recompute: segment ".concat(seg, " not found on target"), path, target); + } + + return { + v: void 0 + }; + } + + target = target[seg]; + sources = sources.map(function (source) { + return source[seg]; + }).filter(Boolean); + }; + + for (var i = 0; i < path.length; i++) { + var _ret = _loop(i); + + if (_typeof__default(_ret) === "object") return _ret.v; + } + } + } + + if (!target || !sources) { + return; + } + + var keys = allKeys.apply(void 0, _toConsumableArray__default(sources)); // Clean up properties that dont exists anymore + + var targetKeys = Object.keys(target); + + for (var _i = 0, _targetKeys = targetKeys; _i < _targetKeys.length; _i++) { + var key = _targetKeys[_i]; + + if (!keys.includes(key)) { + delete target[key]; + } + } + + var _iterator2 = _createForOfIteratorHelper$3(keys), + _step2; + + try { + var _loop2 = function _loop2() { + var key = _step2.value; + // This assumes consistent types usages for keys across sources + // @ts-ignore + var isObject = false; + + for (var _i2 = 0; _i2 < sources.length; _i2++) { + var source = sources[_i2]; + + if (source && key in source && source[key] !== undefined) { + isObject = isPlainObject(source[key]); + break; + } + } + + if (isObject) { + if (!target[key]) { + target[key] = {}; + } + + var _keySources = []; + + var _iterator3 = _createForOfIteratorHelper$3(sources), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _source2 = _step3.value; + + if (key in _source2) { + // @ts-ignore + _keySources.push(_source2[key]); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + recompute(context, [].concat(_toConsumableArray__default(path), [key]), target[key], _keySources); + return "continue"; + } // Ensure the target is an array if source is an array and target is empty + // @ts-ignore + + + if (!target[key] && isArray(sources[0][key])) { + target[key] = []; + } - const createMergedObject = (resolve, active) => { - const sources = []; - const context = { - active, - resolve, - sources - }; - const compute = () => recompute(context); - return { - context, - compute, - addSource: (source, resolveContext, recompute = false) => { - const proxy = createProxy(context, source, resolveContext || {}); - if (recompute) { - compute(); - } - return proxy; - }, - delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); - if (index > -1) { - sources.splice(index, 1); - if (recompute) { - compute(); - } - return true; - } - return false; - } - }; + var keyContexts = []; + var keySources = pluck(sources, key, function (source) { + return keyContexts.push(source[RESOLVE_CONTEXT]); + }); + var resolved = context.resolve(keySources, keyContexts, target[key], key, path); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } + + target[key] = resolved; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret2 = _loop2(); + + if (_ret2 === "continue") continue; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + }; + + function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(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$2(o, minLen); } + + function _arrayLikeToArray$2(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; } + var createProxy = function createProxy(context, target, resolveContext) { + var pathSegments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + var handler = createHandler(context, resolveContext, pathSegments); + var proxy = vue.markRaw(new Proxy(target, handler)); + + if (!pathSegments.length && context.sources) { + context.sources.push(proxy); + } + + return proxy; + }; + var createHandler = function createHandler(context, resolveContext) { + var pathSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + return { + get: function get(target, key, receiver) { + if (key === IS_PROXY) { + return true; + } + + if (key === PROXY_SOURCES) { + return context.sources; + } + + if (key === PROXY_TARGET) { + return target; + } + + if (key === RESOLVE_CONTEXT) { + return resolveContext; + } + + var value = Reflect.get(target, key, receiver); + + if (!isObject(value)) { + return value; + } // Also return a merge proxy for nested objects + + + if (!value[IS_PROXY]) { + var keyPath = [].concat(_toConsumableArray__default(pathSegments), [key]); + value = createProxy(context, value, resolveContext, keyPath); + Reflect.set(target, key, value); + } + + return value; + }, + set: function set(target, key, value) { + var success = Reflect.set(target, key, value); // console.warn(success, 'PROXY SET\nkey:', key, '\nvalue:', value, '\npath:', pathSegments, '\ntarget:', isArray(target), target, '\ncontext:\n', context) + + if (success) { + var isArrayItem = isArray(target); + var hasArrayParent = false; + var proxies = context.sources, + active = context.active; + var activeSegmentKey; + var index = 0; + + var _iterator = _createForOfIteratorHelper$2(pathSegments), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var segment = _step.value; + proxies = pluck(proxies, segment); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + break; + } + + if (isArray(active)) { + hasArrayParent = true; + } + + active = active[segment]; + index++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + if (hasArrayParent) { + // TODO: fix that we dont have to recompute the full merged object + // we should only have to recompute the branch that has changed + // but there is an issue here with supporting both arrays of strings + // as collections (parent vs parent of parent we need to trigger the + // update from) + recompute(context); + return success; + } else if (isPlainObject(value)) { + // if an object was assigned to this key make sure to recompute all + // of its individual properies + recompute(context, pathSegments); + return success; + } + + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); // Ensure to clone if value is an object, cause sources is an array of + // the sourceProxies and not the sources so we could trigger an endless loop when + // updating a prop on an obj as the prop on the active object refers to + // a prop on a proxy + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', isArrayItem, key, '\nresolved:\n', resolved, '\nsources:\n', context.sources, '\nactive:\n', active, Object.keys(active)) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } // console.log('CONTEXT.ACTIVE', context.active, '\nparent:\n', target) + + + return success; + }, + deleteProperty: function deleteProperty(target, key) { + var success = Reflect.deleteProperty(target, key); // console.warn('PROXY DELETE\nkey:', key, '\npath:', pathSegments, '\nparent:', isArray(target), target) + + if (success) { + var isArrayItem = isArray(target); + var activeSegmentKey; + var proxies = context.sources; + var active = context.active; + var index = 0; + + var _iterator2 = _createForOfIteratorHelper$2(pathSegments), + _step2; + + try { + var _loop = function _loop() { + var segment = _step2.value; + // @ts-ignore + proxies = proxies.map(function (proxy) { + return proxy && proxy[segment]; + }); + + if (isArrayItem && index === pathSegments.length - 1) { + activeSegmentKey = segment; + return "break"; + } + + active = active[segment]; + index++; + }; + + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ret = _loop(); + + if (_ret === "break") break; + } // Check if the key still exists in one of the sourceProxies, + // if so resolve the new value, if not remove the key + + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + if (proxies.some(function (proxy) { + return proxy && key in proxy; + })) { + var keyContexts = []; + var keySources; + + if (isArrayItem) { + keySources = proxies; + keyContexts = proxies.map(function (proxy) { + return proxy[RESOLVE_CONTEXT]; + }); + } else { + keySources = pluck(proxies, key, function (proxy) { + return keyContexts.push(proxy[RESOLVE_CONTEXT]); + }); + } + + var resolved = context.resolve(keySources, keyContexts, active, key, pathSegments); + + if (isPlainObject(resolved)) { + resolved = clone(resolved); + } // console.log('SET VALUE', resolved) + + + if (isArrayItem && activeSegmentKey) { + active[activeSegmentKey] = resolved; + } else { + active[key] = resolved; + } + } else { + delete active[key]; + } + } + + return success; + } + }; }; - const cachedElements = {}; - function renderMeta(context, key, data, config) { - // console.info('renderMeta', key, data, config) - if ('attributesFor' in config) { - return renderAttributes(context, key, data, config); - } - if ('group' in config) { - return renderGroup(context, key, data, config); - } - return renderTag(context, key, data, config); - } - function renderGroup(context, key, data, config) { - // console.info('renderGroup', key, data, config) - if (isArray(data)) { - { - // eslint-disable-next-line no-console - console.warn('Specifying an array for group properties isnt supported'); - } - // config.attributes = getConfigKey([key, config.tag], 'attributes', config) - return []; - } - return Object.keys(data) - .map((childKey) => { - const groupConfig = { - group: key, - data - }; - if (config.namespaced) { - groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; - } - else if (config.namespacedAttribute) { - const namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; - groupConfig.fullName = `${namespace}:${childKey}`; - groupConfig.slotName = `${namespace}(${childKey})`; - } - return renderTag(context, key, data[childKey], config, groupConfig); - }) - .filter(Boolean) - .flat(); - } - function renderTag(context, key, data, config = {}, groupConfig) { - // console.info('renderTag', key, data, config, groupConfig) - const contentAttributes = ['content', 'json', 'rawContent']; - const getTagConfig = (key) => getTagConfigItem([tag, config.tag], key); - if (isArray(data)) { - return data - .map((child) => { - return renderTag(context, key, child, config, groupConfig); - }) - .filter(Boolean) - .flat(); - } - const { tag = config.tag || key } = data; - let content = ''; - let hasChilds = false; - let isRaw = false; - if (isString(data)) { - content = data; - } - else if (data.children && isArray(data.children)) { - hasChilds = true; - content = data.children.map((child) => { - const data = renderTag(context, key, child, config, groupConfig); - if (isArray(data)) { - return data.map(({ vnode }) => vnode); - } - return data && data.vnode; - }); - } - else { - let i = 0; - for (const contentAttribute of contentAttributes) { - if (!content && data[contentAttribute]) { - if (i === 1) { - content = JSON.stringify(data[contentAttribute]); - } - else { - content = data[contentAttribute]; - } - isRaw = i > 1; - break; - } - i++; - } - } - const fullName = (groupConfig && groupConfig.fullName) || key; - const slotName = (groupConfig && groupConfig.slotName) || key; - let { attrs: attributes } = data; - if (!attributes && typeof data === 'object') { - attributes = { ...data }; - delete attributes.tag; - delete attributes.children; - delete attributes.to; - // cleanup all content attributes - for (const attr of contentAttributes) { - delete attributes[attr]; - } - } - else if (!attributes) { - attributes = {}; - } - if (hasChilds) { - content = getSlotContent(context, slotName, content, data); - } - else { - const contentAsAttribute = !!getTagConfig('contentAsAttribute'); - let { valueAttribute } = config; - if (!valueAttribute && contentAsAttribute) { - const [tagAttribute] = getTagConfig('attributes'); - valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; - } - if (!valueAttribute) { - content = getSlotContent(context, slotName, content, data); - } - else { - const { nameless } = config; - if (!nameless) { - const keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); - if (keyAttribute) { - attributes[keyAttribute] = fullName; - } - } - attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); - content = ''; - } - } - const finalTag = groupConfig && groupConfig.tagNamespace - ? `${groupConfig.tagNamespace}:${tag}` - : tag; - if (finalTag === 'title' && !context.isSSR) { - document.title = content; - return; - } - // console.info('FINAL TAG', finalTag) - // console.log(' ATTRIBUTES', attributes) - // console.log(' CONTENT', content) - // console.log(data, attributes, config) - if (isRaw && content) { - attributes.innerHTML = content; - } - // Ignore empty string content - const vnode = vue.h(finalTag, attributes, content || undefined); - return { - to: data.to, - vnode - }; - } - function renderAttributes(context, key, data, config) { - // console.info('renderAttributes', key, data, config) - const { attributesFor } = config; - if (!attributesFor || !data) { - return; - } - if (context.isSSR) { - // render attributes in a placeholder vnode so Vue - // will render the string for us - return { - to: '', - vnode: vue.h(`ssr-${attributesFor}`, data) - }; - } - if (!cachedElements[attributesFor]) { - const [el, el2] = Array.from(document.querySelectorAll(attributesFor)); - if (!el) { - // eslint-disable-next-line no-console - console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); - return; - } - if (el2) { - // eslint-disable-next-line no-console - console.warn('Found multiple elements for selector', attributesFor); - } - cachedElements[attributesFor] = { - el, - attrs: [] - }; - } - const { el, attrs } = cachedElements[attributesFor]; - for (const attr in data) { - let content = getSlotContent(context, `${key}(${attr})`, data[attr], data); - if (isArray(content)) { - content = content.join(','); - } - el.setAttribute(attr, content || ''); - if (!attrs.includes(attr)) { - attrs.push(attr); - } - } - const attrsToRemove = attrs.filter(attr => !data[attr]); - for (const attr of attrsToRemove) { - el.removeAttribute(attr); - } - } - function getSlotContent({ metainfo, slots }, slotName, content, groupConfig) { - const slot = slots && slots[slotName]; - if (!slot || !isFunction(slot)) { - return content; - } - const slotScopeProps = { - content, - metainfo - }; - if (groupConfig && groupConfig.group) { - const { group, data } = groupConfig; - slotScopeProps[group] = data; - } - const slotContent = slot(slotScopeProps); - if (slotContent && slotContent.length) { - const { children } = slotContent[0]; - return children ? children.toString() : ''; - } - return content; + var createMergedObject = function createMergedObject(resolve, active) { + var sources = []; + var context = { + active: active, + resolve: resolve, + sources: sources + }; + + var compute = function compute() { + return recompute(context); + }; + + return { + context: context, + compute: compute, + addSource: function addSource(source, resolveContext) { + var recompute = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var proxy = createProxy(context, source, resolveContext || {}); + + if (recompute) { + compute(); + } + + return proxy; + }, + delSource: function delSource(sourceOrProxy) { + var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var index = sources.findIndex(function (source) { + return source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy; + }); + + if (index > -1) { + sources.splice(index, 1); + + if (recompute) { + compute(); + } + + return true; + } + + return false; + } + }; + }; + + function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + + function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(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$1(o, minLen); } + + function _arrayLikeToArray$1(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; } + var cachedElements = {}; + function renderMeta(context, key, data, config) { + // console.info('renderMeta', key, data, config) + if ('attributesFor' in config) { + return renderAttributes(context, key, data, config); + } + + if ('group' in config) { + return renderGroup(context, key, data, config); + } + + return renderTag(context, key, data, config); } + function renderGroup(context, key, data, config) { + // console.info('renderGroup', key, data, config) + if (isArray(data)) { + { + // eslint-disable-next-line no-console + console.warn('Specifying an array for group properties isnt supported'); + } // config.attributes = getConfigKey([key, config.tag], 'attributes', config) + - const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; - const PolySymbol = (name) => - // vm = vue meta - hasSymbol - ? Symbol('[vue-meta]: ' + name ) - : ('[vue-meta]: ' ) + name; - const metaActiveKey = /*#__PURE__*/ PolySymbol('meta_active' ); + return []; + } + + return Object.keys(data).map(function (childKey) { + var groupConfig = { + group: key, + data: data + }; + + if (config.namespaced) { + groupConfig.tagNamespace = config.namespaced === true ? key : config.namespaced; + } else if (config.namespacedAttribute) { + var namespace = config.namespacedAttribute === true ? key : config.namespacedAttribute; + groupConfig.fullName = "".concat(namespace, ":").concat(childKey); + groupConfig.slotName = "".concat(namespace, "(").concat(childKey, ")"); + } + + return renderTag(context, key, data[childKey], config, groupConfig); + }).filter(Boolean).flat(); + } + function renderTag(context, key, data) { + var config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var groupConfig = arguments.length > 4 ? arguments[4] : undefined; + // console.info('renderTag', key, data, config, groupConfig) + var contentAttributes = ['content', 'json', 'rawContent']; + + var getTagConfig = function getTagConfig(key) { + return getTagConfigItem([tag, config.tag], key); + }; + + if (isArray(data)) { + return data.map(function (child) { + return renderTag(context, key, child, config, groupConfig); + }).filter(Boolean).flat(); + } + + var _data$tag = data.tag, + tag = _data$tag === void 0 ? config.tag || key : _data$tag; + var content = ''; + var hasChilds = false; + var isRaw = false; + + if (isString(data)) { + content = data; + } else if (data.children && isArray(data.children)) { + hasChilds = true; + content = data.children.map(function (child) { + var data = renderTag(context, key, child, config, groupConfig); + + if (isArray(data)) { + return data.map(function (_ref) { + var vnode = _ref.vnode; + return vnode; + }); + } + + return data && data.vnode; + }); + } else { + var i = 0; + + var _iterator = _createForOfIteratorHelper$1(contentAttributes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var contentAttribute = _step.value; + + if (!content && data[contentAttribute]) { + if (i === 1) { + content = JSON.stringify(data[contentAttribute]); + } else { + content = data[contentAttribute]; + } + + isRaw = i > 1; + break; + } + + i++; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + var fullName = groupConfig && groupConfig.fullName || key; + var slotName = groupConfig && groupConfig.slotName || key; + var attributes = data.attrs; + + if (!attributes && _typeof__default(data) === 'object') { + attributes = _objectSpread({}, data); + delete attributes.tag; + delete attributes.children; + delete attributes.to; // cleanup all content attributes + + var _iterator2 = _createForOfIteratorHelper$1(contentAttributes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var attr = _step2.value; + delete attributes[attr]; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } else if (!attributes) { + attributes = {}; + } + + if (hasChilds) { + content = getSlotContent(context, slotName, content, data); + } else { + var contentAsAttribute = !!getTagConfig('contentAsAttribute'); + var valueAttribute = config.valueAttribute; + + if (!valueAttribute && contentAsAttribute) { + var _getTagConfig = getTagConfig('attributes'), + _getTagConfig2 = _slicedToArray__default(_getTagConfig, 1), + tagAttribute = _getTagConfig2[0]; + + valueAttribute = isString(contentAsAttribute) ? contentAsAttribute : tagAttribute; + } + + if (!valueAttribute) { + content = getSlotContent(context, slotName, content, data); + } else { + var nameless = config.nameless; + + if (!nameless) { + var keyAttribute = config.keyAttribute || getTagConfig('keyAttribute'); + + if (keyAttribute) { + attributes[keyAttribute] = fullName; + } + } + + attributes[valueAttribute] = getSlotContent(context, slotName, attributes[valueAttribute] || content, groupConfig); + content = ''; + } + } + + var finalTag = groupConfig && groupConfig.tagNamespace ? "".concat(groupConfig.tagNamespace, ":").concat(tag) : tag; + + if (finalTag === 'title' && !context.isSSR) { + document.title = content; + return; + } // console.info('FINAL TAG', finalTag) + // console.log(' ATTRIBUTES', attributes) + // console.log(' CONTENT', content) + // console.log(data, attributes, config) + + + if (isRaw && content) { + attributes.innerHTML = content; + } // Ignore empty string content + + + var vnode = vue.h(finalTag, attributes, content || undefined); + return { + to: data.to, + vnode: vnode + }; + } + function renderAttributes(context, key, data, config) { + // console.info('renderAttributes', key, data, config) + var attributesFor = config.attributesFor; + + if (!attributesFor || !data) { + return; + } + + if (context.isSSR) { + // render attributes in a placeholder vnode so Vue + // will render the string for us + return { + to: '', + vnode: vue.h("ssr-".concat(attributesFor), data) + }; + } + + if (!cachedElements[attributesFor]) { + var _Array$from = Array.from(document.querySelectorAll(attributesFor)), + _Array$from2 = _slicedToArray__default(_Array$from, 2), + _el = _Array$from2[0], + el2 = _Array$from2[1]; + + if (!_el) { + // eslint-disable-next-line no-console + console.error('Could not find element for selector', attributesFor, ', won\'t render attributes'); + return; + } + + if (el2) { + // eslint-disable-next-line no-console + console.warn('Found multiple elements for selector', attributesFor); + } + + cachedElements[attributesFor] = { + el: _el, + attrs: [] + }; + } + + var _cachedElements$attri = cachedElements[attributesFor], + el = _cachedElements$attri.el, + attrs = _cachedElements$attri.attrs; + + for (var attr in data) { + var content = getSlotContent(context, "".concat(key, "(").concat(attr, ")"), data[attr], data); + + if (isArray(content)) { + content = content.join(','); + } + + el.setAttribute(attr, content || ''); + + if (!attrs.includes(attr)) { + attrs.push(attr); + } + } + + var attrsToRemove = attrs.filter(function (attr) { + return !data[attr]; + }); + + var _iterator3 = _createForOfIteratorHelper$1(attrsToRemove), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _attr = _step3.value; + el.removeAttribute(_attr); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + } + function getSlotContent(_ref2, slotName, content, groupConfig) { + var metainfo = _ref2.metainfo, + slots = _ref2.slots; + var slot = slots && slots[slotName]; + + if (!slot || !isFunction(slot)) { + return content; + } + + var slotScopeProps = { + content: content, + metainfo: metainfo + }; + + if (groupConfig && groupConfig.group) { + var group = groupConfig.group, + data = groupConfig.data; + slotScopeProps[group] = data; + } + + var slotContent = slot(slotScopeProps); + + if (slotContent && slotContent.length) { + var children = slotContent[0].children; + return children ? children.toString() : ''; + } + + return content; + } + + var hasSymbol = typeof Symbol === 'function' && _typeof__default(Symbol.toStringTag) === 'symbol'; + var PolySymbol = function PolySymbol(name) { + return (// vm = vue meta + hasSymbol ? Symbol('[vue-meta]: ' + name ) : ('[vue-meta]: ' ) + name + ); + }; + var metaActiveKey = /*#__PURE__*/PolySymbol('meta_active' ); /** * Apply the differences between newSource & oldSource to target - */ - function applyDifference(target, newSource, oldSource) { - for (const key in newSource) { - if (!(key in oldSource)) { - target[key] = newSource[key]; - continue; - } - if (isObject(target[key])) { - applyDifference(target[key], newSource[key], oldSource[key]); - continue; - } - if (newSource[key] !== oldSource[key]) { - target[key] = newSource[key]; - } - } - for (const key in oldSource) { - if (!newSource || !(key in newSource)) { - delete target[key]; - } - } + */ + + function applyDifference(target, newSource, oldSource) { + for (var key in newSource) { + if (!(key in oldSource)) { + target[key] = newSource[key]; + continue; + } + + if (isObject(target[key])) { + applyDifference(target[key], newSource[key], oldSource[key]); + continue; + } + + if (newSource[key] !== oldSource[key]) { + target[key] = newSource[key]; + } + } + + for (var _key in oldSource) { + if (!newSource || !(_key in newSource)) { + delete target[_key]; + } + } } - function getCurrentManager(vm) { - if (!vm) { - vm = vue.getCurrentInstance() || undefined; - } - if (!vm) { - return undefined; - } - return vm.appContext.config.globalProperties.$metaManager; - } - function useMeta(source, manager) { - const vm = vue.getCurrentInstance() || undefined; - if (!manager && vm) { - manager = getCurrentManager(vm); - } - if (!manager) { - throw new Error('No manager or current instance'); - } - if (vue.isProxy(source)) { - vue.watch(source, (newSource, oldSource) => { - applyDifference(metaProxy.meta, newSource, oldSource); - }); - source = source.value; - } - const metaProxy = manager.addMeta(source, vm); - return metaProxy; - } - function useActiveMeta() { - return vue.inject(metaActiveKey); + function getCurrentManager(vm) { + if (!vm) { + vm = vue.getCurrentInstance() || undefined; + } + + if (!vm) { + return undefined; + } + + return vm.appContext.config.globalProperties.$metaManager; } + function useMeta(source, manager) { + var vm = vue.getCurrentInstance() || undefined; + + if (!manager && vm) { + manager = getCurrentManager(vm); + } + + if (!manager) { + throw new Error('No manager or current instance'); + } - const MetainfoImpl = vue.defineComponent({ - name: 'Metainfo', - inheritAttrs: false, - setup(_, { slots }) { - return () => { - const manager = getCurrentManager(); - if (!manager) { - return; - } - return manager.render({ slots }); - }; - } - }); - const Metainfo = MetainfoImpl; - - const ssrAttribute = 'data-vm-ssr'; - function addVnode(isSSR, teleports, to, vnodes) { - const nodes = (isArray(vnodes) ? vnodes : [vnodes]); - if (!isSSR) { - // Comments shouldnt have any use on the client as they are not reactive anyway - nodes.forEach((vnode, idx) => { - if (vnode.type === vue.Comment) { - nodes.splice(idx, 1); - } - }); - // only add ssrAttribute's for real meta tags - } - else if (!to.endsWith('Attrs')) { - nodes.forEach((vnode) => { - if (!vnode.props) { - vnode.props = {}; - } - vnode.props[ssrAttribute] = true; - }); - } - if (!teleports[to]) { - teleports[to] = []; - } - teleports[to].push(...nodes); - } - const createMetaManager = (isSSR = false, config, resolver) => MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); - class MetaManager { - isSSR = false; - config; - target; - resolver; - ssrCleanedUp = false; - constructor(isSSR, config, target, resolver) { - this.isSSR = isSSR; - this.config = config; - this.target = target; - if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { - this.resolver = resolver; - } - } - static create = (isSSR, config, resolver) => { - const resolve = (options, contexts, active, key, pathSegments) => { - if (isFunction(resolver)) { - return resolver(options, contexts, active, key, pathSegments); - } - return resolver.resolve(options, contexts, active, key, pathSegments); - }; - const active = vue.reactive({}); - const mergedObject = createMergedObject(resolve, active); - // TODO: validate resolver - const manager = new MetaManager(isSSR, config, mergedObject, resolver); - return manager; - }; - install(app) { - app.component('Metainfo', Metainfo); - app.config.globalProperties.$metaManager = this; - app.provide(metaActiveKey, this.target.context.active); - } - addMeta(metadata, vm) { - if (!vm) { - vm = vue.getCurrentInstance() || undefined; - } - const metaGuards = ({ - removed: [] - }); - const resolveContext = { vm }; - const { resolver } = this; - if (resolver && resolver.setup) { - resolver.setup(resolveContext); - } - // TODO: optimize initial compute (once) - const meta = this.target.addSource(metadata, resolveContext, true); - const onRemoved = (removeGuard) => metaGuards.removed.push(removeGuard); - const unmount = (ignoreGuards) => this.unmount(!!ignoreGuards, meta, metaGuards, vm); - if (vm) { - vue.onUnmounted(unmount); - } - return { - meta, - onRemoved, - unmount - }; - } - unmount(ignoreGuards, meta, metaGuards, vm) { - if (vm) { - const { $el } = vm.proxy; - // Wait for element to be removed from DOM - if ($el && $el.offsetParent) { - let observer = new MutationObserver((records) => { - for (const { removedNodes } of records) { - if (!removedNodes) { - continue; - } - removedNodes.forEach((el) => { - if (el === $el && observer) { - observer.disconnect(); - observer = undefined; - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - }); - } - }); - observer.observe($el.parentNode, { childList: true }); - return; - } - } - this.reallyUnmount(ignoreGuards, meta, metaGuards); - } - async reallyUnmount(ignoreGuards, meta, metaGuards) { - this.target.delSource(meta); - if (!ignoreGuards && metaGuards) { - await Promise.all(metaGuards.removed.map(removeGuard => removeGuard())); - } - } - render({ slots } = {}) { - const active = this.target.context.active; - // TODO: clean this method - const { isSSR } = this; - // cleanup ssr tags if not yet done - if (!isSSR && !this.ssrCleanedUp) { - this.ssrCleanedUp = true; - const cleanUpSSR = () => { - const ssrTags = document.querySelectorAll(`[${ssrAttribute}]`); - if (ssrTags && ssrTags.length) { - ssrTags.forEach(el => el.parentNode && el.parentNode.removeChild(el)); - } - }; - if (document.readyState === 'loading') { - // Listen for DOM loaded because tags in the body couldnt - // have loaded yet once the manager does it first render - // (preferable there should only be one meta render on hydration) - window.addEventListener('DOMContentLoaded', cleanUpSSR, { once: true }); - } - else { - cleanUpSSR(); - } - } - const teleports = {}; - for (const key in active) { - const config = this.config[key] || {}; - let renderedNodes = renderMeta({ isSSR, metainfo: active, slots }, key, active[key], config); - if (!renderedNodes) { - continue; - } - if (!isArray(renderedNodes)) { - renderedNodes = [renderedNodes]; - } - let defaultTo = key !== 'base' && active[key].to; - if (!defaultTo && 'to' in config) { - defaultTo = config.to; - } - if (!defaultTo && 'attributesFor' in config) { - defaultTo = key; - } - for (const { to, vnode } of renderedNodes) { - addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); - } - } - if (slots) { - for (const slotName in slots) { - const tagName = slotName === 'default' ? 'head' : slotName; - // Only teleport the contents of head/body slots - if (tagName !== 'head' && tagName !== 'body') { - continue; - } - const slot = slots[slotName]; - if (isFunction(slot)) { - addVnode(this.isSSR, teleports, tagName, slot({ metainfo: active })); - } - } - } - return Object.keys(teleports).map((to) => { - const teleport = teleports[to]; - return vue.h(vue.Teleport, { to }, teleport); - }); - } + if (vue.isProxy(source)) { + vue.watch(source, function (newSource, oldSource) { + applyDifference(metaProxy.meta, newSource, oldSource); + }); + source = source.value; + } + + var metaProxy = manager.addMeta(source, vm); + return metaProxy; + } + function useActiveMeta() { + return vue.inject(metaActiveKey); } - const defaultOptions = { - keyName: 'metaInfo' - }; - const createMixin = options => ({ - created() { - const instance = vue.getCurrentInstance(); - if (!instance?.type || !(options.keyName in instance.type)) { - return; - } - const metaInfo = instance.type[options.keyName]; - if (isFunction(metaInfo)) { - const computedMetaInfo = vue.computed(metaInfo.bind(this)); - useMeta(computedMetaInfo); - } - else { - useMeta(metaInfo); - } - } - }); - const install = (app, _options = {}) => { - const options = Object.assign({}, defaultOptions, _options); - app.mixin(createMixin(options)); + var MetainfoImpl = vue.defineComponent({ + name: 'Metainfo', + inheritAttrs: false, + setup: function setup(_, _ref) { + var slots = _ref.slots; + return function () { + var manager = getCurrentManager(); + + if (!manager) { + return; + } + + return manager.render({ + slots: slots + }); + }; + } + }); + var Metainfo = MetainfoImpl; + + function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + + 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; } + var ssrAttribute = 'data-vm-ssr'; + function addVnode(isSSR, teleports, to, vnodes) { + var _teleports$to; + + var nodes = isArray(vnodes) ? vnodes : [vnodes]; + + if (!isSSR) { + // Comments shouldnt have any use on the client as they are not reactive anyway + nodes.forEach(function (vnode, idx) { + if (vnode.type === vue.Comment) { + nodes.splice(idx, 1); + } + }); // only add ssrAttribute's for real meta tags + } else if (!to.endsWith('Attrs')) { + nodes.forEach(function (vnode) { + if (!vnode.props) { + vnode.props = {}; + } + + vnode.props[ssrAttribute] = true; + }); + } + + if (!teleports[to]) { + teleports[to] = []; + } + + (_teleports$to = teleports[to]).push.apply(_teleports$to, _toConsumableArray__default(nodes)); + } + var createMetaManager = function createMetaManager() { + var isSSR = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var config = arguments.length > 1 ? arguments[1] : undefined; + var resolver = arguments.length > 2 ? arguments[2] : undefined; + return MetaManager.create(isSSR, config || defaultConfig, resolver || defaultResolver); + }; + var MetaManager = /*#__PURE__*/function () { + function MetaManager(isSSR, config, target, resolver) { + _classCallCheck__default(this, MetaManager); + + _defineProperty__default(this, "isSSR", false); + + _defineProperty__default(this, "config", void 0); + + _defineProperty__default(this, "target", void 0); + + _defineProperty__default(this, "resolver", void 0); + + _defineProperty__default(this, "ssrCleanedUp", false); + + this.isSSR = isSSR; + this.config = config; + this.target = target; + + if (resolver && 'setup' in resolver && isFunction(resolver.setup)) { + this.resolver = resolver; + } + } + + _createClass__default(MetaManager, [{ + key: "install", + value: function install(app) { + app.component('Metainfo', Metainfo); + app.config.globalProperties.$metaManager = this; + app.provide(metaActiveKey, this.target.context.active); + } + }, { + key: "addMeta", + value: function addMeta(metadata, vm) { + var _this = this; + + if (!vm) { + vm = vue.getCurrentInstance() || undefined; + } + + var metaGuards = { + removed: [] + }; + var resolveContext = { + vm: vm + }; + var resolver = this.resolver; + + if (resolver && resolver.setup) { + resolver.setup(resolveContext); + } // TODO: optimize initial compute (once) + + + var meta = this.target.addSource(metadata, resolveContext, true); + + var onRemoved = function onRemoved(removeGuard) { + return metaGuards.removed.push(removeGuard); + }; + + var unmount = function unmount(ignoreGuards) { + return _this.unmount(!!ignoreGuards, meta, metaGuards, vm); + }; + + if (vm) { + vue.onUnmounted(unmount); + } + + return { + meta: meta, + onRemoved: onRemoved, + unmount: unmount + }; + } + }, { + key: "unmount", + value: function unmount(ignoreGuards, meta, metaGuards, vm) { + var _this2 = this; + + if (vm) { + var $el = vm.proxy.$el; // Wait for element to be removed from DOM + + if ($el && $el.offsetParent) { + var observer = new MutationObserver(function (records) { + var _iterator = _createForOfIteratorHelper(records), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var removedNodes = _step.value.removedNodes; + + if (!removedNodes) { + continue; + } + + removedNodes.forEach(function (el) { + if (el === $el && observer) { + observer.disconnect(); + observer = undefined; + + _this2.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }); + observer.observe($el.parentNode, { + childList: true + }); + return; + } + } + + this.reallyUnmount(ignoreGuards, meta, metaGuards); + } + }, { + key: "reallyUnmount", + value: function () { + var _reallyUnmount = _asyncToGenerator__default( /*#__PURE__*/_regeneratorRuntime__default.mark(function _callee(ignoreGuards, meta, metaGuards) { + return _regeneratorRuntime__default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + this.target.delSource(meta); + + if (!(!ignoreGuards && metaGuards)) { + _context.next = 4; + break; + } + + _context.next = 4; + return Promise.all(metaGuards.removed.map(function (removeGuard) { + return removeGuard(); + })); + + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function reallyUnmount(_x, _x2, _x3) { + return _reallyUnmount.apply(this, arguments); + } + + return reallyUnmount; + }() + }, { + key: "render", + value: function render() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + slots = _ref.slots; + + var active = this.target.context.active; // TODO: clean this method + + var isSSR = this.isSSR; // cleanup ssr tags if not yet done + + if (!isSSR && !this.ssrCleanedUp) { + this.ssrCleanedUp = true; + + var cleanUpSSR = function cleanUpSSR() { + var ssrTags = document.querySelectorAll("[".concat(ssrAttribute, "]")); + + if (ssrTags && ssrTags.length) { + ssrTags.forEach(function (el) { + return el.parentNode && el.parentNode.removeChild(el); + }); + } + }; + + if (document.readyState === 'loading') { + // Listen for DOM loaded because tags in the body couldnt + // have loaded yet once the manager does it first render + // (preferable there should only be one meta render on hydration) + window.addEventListener('DOMContentLoaded', cleanUpSSR, { + once: true + }); + } else { + cleanUpSSR(); + } + } + + var teleports = {}; + + for (var key in active) { + var config = this.config[key] || {}; + var renderedNodes = renderMeta({ + isSSR: isSSR, + metainfo: active, + slots: slots + }, key, active[key], config); + + if (!renderedNodes) { + continue; + } + + if (!isArray(renderedNodes)) { + renderedNodes = [renderedNodes]; + } + + var defaultTo = key !== 'base' && active[key].to; + + if (!defaultTo && 'to' in config) { + defaultTo = config.to; + } + + if (!defaultTo && 'attributesFor' in config) { + defaultTo = key; + } + + var _iterator2 = _createForOfIteratorHelper(renderedNodes), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _step2.value, + to = _step2$value.to, + vnode = _step2$value.vnode; + addVnode(this.isSSR, teleports, to || defaultTo || 'head', vnode); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + if (slots) { + for (var slotName in slots) { + var tagName = slotName === 'default' ? 'head' : slotName; // Only teleport the contents of head/body slots + + if (tagName !== 'head' && tagName !== 'body') { + continue; + } + + var slot = slots[slotName]; + + if (isFunction(slot)) { + addVnode(this.isSSR, teleports, tagName, slot({ + metainfo: active + })); + } + } + } + + return Object.keys(teleports).map(function (to) { + var teleport = teleports[to]; + return vue.h(vue.Teleport, { + to: to + }, teleport); + }); + } + }]); + + return MetaManager; + }(); + + _defineProperty__default(MetaManager, "create", function (isSSR, config, resolver) { + var resolve = function resolve(options, contexts, active, key, pathSegments) { + if (isFunction(resolver)) { + return resolver(options, contexts, active, key, pathSegments); + } + + return resolver.resolve(options, contexts, active, key, pathSegments); + }; + + var active = vue.reactive({}); + var mergedObject = createMergedObject(resolve, active); // TODO: validate resolver + + var manager = new MetaManager(isSSR, config, mergedObject, resolver); + return manager; + }); + + var defaultOptions = { + keyName: 'metaInfo' + }; + var createMixin = function createMixin(options) { + return { + created: function created() { + var instance = vue.getCurrentInstance(); + + if (!(instance !== null && instance !== void 0 && instance.type) || !(options.keyName in instance.type)) { + return; + } + + var metaInfo = instance.type[options.keyName]; + + if (isFunction(metaInfo)) { + var computedMetaInfo = vue.computed(metaInfo.bind(this)); + useMeta(computedMetaInfo); + } else { + useMeta(metaInfo); + } + } + }; + }; + var install = function install(app) { + var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var options = Object.assign({}, defaultOptions, _options); + app.mixin(createMixin(options)); }; exports.createMetaManager = createMetaManager; @@ -984,4 +1469,4 @@ var VueMeta = (function (exports, vue) { return exports; -}({}, Vue)); +})({}, _asyncToGenerator, _classCallCheck, _createClass, _defineProperty, _toConsumableArray, _regeneratorRuntime, Vue, _typeof, _slicedToArray); diff --git a/dist/vue-meta.global.min.js b/dist/vue-meta.global.min.js index 253229ae..5caf08bc 100644 --- a/dist/vue-meta.global.min.js +++ b/dist/vue-meta.global.min.js @@ -5,4 +5,4 @@ * - All the amazing contributors * @license MIT */ -var VueMeta=function(t,e){"use strict";const r=(t,e)=>(r,n)=>{let o=-1;if(n.reduce(((e,r,n)=>{const s=t(e,r);return s!==e?(o=n,s):e}),e),o>-1)return r[o]},n=r(((t,e)=>{const{depth:r}=e;return!t||r>t?r:t}));var o=Object.freeze({__proto__:null,setup:t=>{let e=0;if(t.vm){let{vm:r}=t;do{r.parent&&(e++,r=r.parent)}while(r&&r.parent&&r!==r.root)}t.depth=e},resolve:n});const s={body:{tag:"script",to:"body"},base:{valueAttribute:"href"},charset:{tag:"meta",nameless:!0,valueAttribute:"charset"},description:{tag:"meta"},og:{group:!0,namespacedAttribute:!0,tag:"meta",keyAttribute:"property"},twitter:{group:!0,namespacedAttribute:!0,tag:"meta"},htmlAttrs:{attributesFor:"html"},headAttrs:{attributesFor:"head"},bodyAttrs:{attributesFor:"body"}},i={title:{attributes:!1},base:{contentAsAttribute:!0,attributes:["href","target"]},meta:{contentAsAttribute:!0,keyAttribute:"name",attributes:["content","name","http-equiv","charset"]},link:{contentAsAttribute:!0,attributes:["href","crossorigin","rel","media","integrity","hreflang","type","referrerpolicy","sizes","imagesrcset","imagesizes","as","color"]},style:{attributes:["media"]},script:{attributes:["src","type","nomodule","async","defer","crossorigin","integrity","referrerpolicy"]},noscript:{attributes:!1}};Object.freeze({}),Object.freeze([]);const c=Array.isArray,a=t=>"function"==typeof t,u=t=>"string"==typeof t,l=t=>null!==t&&"object"==typeof t,f=Object.prototype.toString,d=t=>"[object Object]"===f.call(t),p=Symbol("kIsProxy"),m=Symbol("kProxySources"),g=Symbol("kProxyTarget"),h=Symbol("kResolveContext");function b(t){if(c(t))return t.map(b);if(l(t)){const e={};for(const r in t)e[r]="context"===r?t[r]:b(t[r]);return e}return t}const y=(t,e,r)=>{const n=[];for(const o of t)o&&e in o&&(n.push(o[e]),r&&r(o));return n},v=(t,e=[],r,n)=>{if(!r&&!n&&(({active:r,sources:n}=t),e.length))for(let t=0;tt[o])).filter(Boolean)}if(!r||!n)return;const o=((t,...e)=>{const r=t?Object.keys(t):[];if(e)for(const t of e)if(t&&l(t))for(const e in t)r.includes(e)||r.push(e);return r})(...n),s=Object.keys(r);for(const t of s)o.includes(t)||delete r[t];for(const s of o){let o=!1;for(let t=0;ti.push(t[h])));let u=t.resolve(a,i,r[s],s,e);d(u)&&(u=b(u)),r[s]=u}},S=(t,r,n,o=[])=>{const s=A(t,n,o),i=e.markRaw(new Proxy(r,s));return!o.length&&t.sources&&t.sources.push(i),i},A=(t,e,r=[])=>({get:(n,o,s)=>{if(o===p)return!0;if(o===m)return t.sources;if(o===g)return n;if(o===h)return e;let i=Reflect.get(n,o,s);if(!l(i))return i;if(!i[p]){const s=[...r,o];i=S(t,i,e,s),Reflect.set(n,o,i)}return i},set:(e,n,o)=>{const s=Reflect.set(e,n,o);if(s){const i=c(e);let a,u=!1,{sources:l,active:f}=t,p=0;for(const t of r){if(l=y(l,t),i&&p===r.length-1){a=t;break}c(f)&&(u=!0),f=f[t],p++}if(u)return v(t),s;if(d(o))return v(t,r),s;let m,g=[];i?(m=l,g=l.map((t=>t[h]))):m=y(l,n,(t=>g.push(t[h])));let S=t.resolve(m,g,f,n,r);d(S)&&(S=b(S)),i&&a?f[a]=S:f[n]=S}return s},deleteProperty:(e,n)=>{const o=Reflect.deleteProperty(e,n);if(o){const o=c(e);let s,i=t.sources,a=t.active,u=0;for(const t of r){if(i=i.map((e=>e&&e[t])),o&&u===r.length-1){s=t;break}a=a[t],u++}if(i.some((t=>t&&n in t))){let e,c=[];o?(e=i,c=i.map((t=>t[h]))):e=y(i,n,(t=>c.push(t[h])));let u=t.resolve(e,c,a,n,r);d(u)&&(u=b(u)),o&&s?a[s]=u:a[n]=u}else delete a[n]}return o}}),k={};function j(t,r,n,o){return"attributesFor"in o?function(t,r,n,o){const{attributesFor:s}=o;if(!s||!n)return;if(t.isSSR)return{to:"",vnode:e.h(`ssr-${s}`,n)};if(!k[s]){const[t,e]=Array.from(document.querySelectorAll(s));if(!t)return void console.error("Could not find element for selector",s,", won't render attributes");e&&console.warn("Found multiple elements for selector",s),k[s]={el:t,attrs:[]}}const{el:i,attrs:a}=k[s];for(const e in n){let o=w(t,`${r}(${e})`,n[e],n);c(o)&&(o=o.join(",")),i.setAttribute(e,o||""),a.includes(e)||a.push(e)}const u=a.filter((t=>!n[t]));for(const t of u)i.removeAttribute(t)}(t,r,n,o):"group"in o?function(t,e,r,n){if(c(r))return console.warn("Specifying an array for group properties isnt supported"),[];return Object.keys(r).map((o=>{const s={group:e,data:r};if(n.namespaced)s.tagNamespace=!0===n.namespaced?e:n.namespaced;else if(n.namespacedAttribute){const t=!0===n.namespacedAttribute?e:n.namespacedAttribute;s.fullName=`${t}:${o}`,s.slotName=`${t}(${o})`}return C(t,e,r[o],n,s)})).filter(Boolean).flat()}(t,r,n,o):C(t,r,n,o)}function C(t,r,n,o={},s){const a=["content","json","rawContent"],l=t=>function(t,e){for(const r of t){const t=i[r];if(r&&t)return t[e]}}([f,o.tag],t);if(c(n))return n.map((e=>C(t,r,e,o,s))).filter(Boolean).flat();const{tag:f=o.tag||r}=n;let d="",p=!1,m=!1;if(u(n))d=n;else if(n.children&&c(n.children))p=!0,d=n.children.map((e=>{const n=C(t,r,e,o,s);return c(n)?n.map((({vnode:t})=>t)):n&&n.vnode}));else{let t=0;for(const e of a){if(!d&&n[e]){d=1===t?JSON.stringify(n[e]):n[e],m=t>1;break}t++}}const g=s&&s.fullName||r,h=s&&s.slotName||r;let{attrs:b}=n;if(b||"object"!=typeof n)b||(b={});else{b={...n},delete b.tag,delete b.children,delete b.to;for(const t of a)delete b[t]}if(p)d=w(t,h,d,n);else{const e=!!l("contentAsAttribute");let{valueAttribute:r}=o;if(!r&&e){const[t]=l("attributes");r=u(e)?e:t}if(r){const{nameless:e}=o;if(!e){const t=o.keyAttribute||l("keyAttribute");t&&(b[t]=g)}b[r]=w(t,h,b[r]||d,s),d=""}else d=w(t,h,d,n)}const y=s&&s.tagNamespace?`${s.tagNamespace}:${f}`:f;if("title"===y&&!t.isSSR)return void(document.title=d);m&&d&&(b.innerHTML=d);const v=e.h(y,b,d||void 0);return{to:n.to,vnode:v}}function w({metainfo:t,slots:e},r,n,o){const s=e&&e[r];if(!s||!a(s))return n;const i={content:n,metainfo:t};if(o&&o.group){const{group:t,data:e}=o;i[t]=e}const c=s(i);if(c&&c.length){const{children:t}=c[0];return t?t.toString():""}return n}const M="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,N=(t=>M?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function R(t,e,r){for(const n in e)n in r?l(t[n])?R(t[n],e[n],r[n]):e[n]!==r[n]&&(t[n]=e[n]):t[n]=e[n];for(const n in r)e&&n in e||delete t[n]}function O(t){if(t||(t=e.getCurrentInstance()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function x(t,r){const n=e.getCurrentInstance()||void 0;if(!r&&n&&(r=O(n)),!r)throw new Error("No manager or current instance");e.isProxy(t)&&(e.watch(t,((t,e)=>{R(o.meta,t,e)})),t=t.value);const o=r.addMeta(t,n);return o}const $=e.defineComponent({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=O();if(t)return t.render({slots:e})}}),P="data-vm-ssr";function F(t,r,n,o){const s=c(o)?o:[o];t?n.endsWith("Attrs")||s.forEach((t=>{t.props||(t.props={}),t.props[P]=!0})):s.forEach(((t,r)=>{t.type===e.Comment&&s.splice(r,1)})),r[n]||(r[n]=[]),r[n].push(...s)}class I{isSSR=!1;config;target;resolver;ssrCleanedUp=!1;constructor(t,e,r,n){this.isSSR=t,this.config=e,this.target=r,n&&"setup"in n&&a(n.setup)&&(this.resolver=n)}static create=(t,r,n)=>{const o=((t,e)=>{const r=[],n={active:e,resolve:t,sources:r},o=()=>v(n);return{context:n,compute:o,addSource:(t,e,r=!1)=>{const s=S(n,t,e||{});return r&&o(),s},delSource:(t,e=!0)=>{const n=r.findIndex((e=>e===t||e[g]===t));return n>-1&&(r.splice(n,1),e&&o(),!0)}}})(((t,e,r,o,s)=>a(n)?n(t,e,r,o,s):n.resolve(t,e,r,o,s)),e.reactive({}));return new I(t,r,o,n)};install(t){t.component("Metainfo",$),t.config.globalProperties.$metaManager=this,t.provide(N,this.target.context.active)}addMeta(t,r){r||(r=e.getCurrentInstance()||void 0);const n={removed:[]},o={vm:r},{resolver:s}=this;s&&s.setup&&s.setup(o);const i=this.target.addSource(t,o,!0),c=t=>this.unmount(!!t,i,n,r);return r&&e.onUnmounted(c),{meta:i,onRemoved:t=>n.removed.push(t),unmount:c}}unmount(t,e,r,n){if(n){const{$el:o}=n.proxy;if(o&&o.offsetParent){let n=new MutationObserver((s=>{for(const{removedNodes:i}of s)i&&i.forEach((s=>{s===o&&n&&(n.disconnect(),n=void 0,this.reallyUnmount(t,e,r))}))}));return void n.observe(o.parentNode,{childList:!0})}}this.reallyUnmount(t,e,r)}async reallyUnmount(t,e,r){this.target.delSource(e),!t&&r&&await Promise.all(r.removed.map((t=>t())))}render({slots:t}={}){const r=this.target.context.active,{isSSR:n}=this;if(!n&&!this.ssrCleanedUp){this.ssrCleanedUp=!0;const t=()=>{const t=document.querySelectorAll("[data-vm-ssr]");t&&t.length&&t.forEach((t=>t.parentNode&&t.parentNode.removeChild(t)))};"loading"===document.readyState?window.addEventListener("DOMContentLoaded",t,{once:!0}):t()}const o={};for(const e in r){const s=this.config[e]||{};let i=j({isSSR:n,metainfo:r,slots:t},e,r[e],s);if(!i)continue;c(i)||(i=[i]);let a="base"!==e&&r[e].to;!a&&"to"in s&&(a=s.to),!a&&"attributesFor"in s&&(a=e);for(const{to:t,vnode:e}of i)F(this.isSSR,o,t||a||"head",e)}if(t)for(const e in t){const n="default"===e?"head":e;if("head"!==n&&"body"!==n)continue;const s=t[e];a(s)&&F(this.isSSR,o,n,s({metainfo:r}))}return Object.keys(o).map((t=>e.h(e.Teleport,{to:t},o[t])))}}const U={keyName:"metaInfo"},_=t=>({created(){const r=e.getCurrentInstance();if(!r?.type||!(t.keyName in r.type))return;const n=r.type[t.keyName];if(a(n)){x(e.computed(n.bind(this)))}else x(n)}});return t.createMetaManager=(t=!1,e,r)=>I.create(t,e||s,r||o),t.deepestResolver=o,t.defaultConfig=s,t.getCurrentManager=O,t.plugin=(t,e={})=>{const r=Object.assign({},U,e);t.mixin(_(r))},t.resolveOption=r,t.useActiveMeta=function(){return e.inject(N)},t.useMeta=x,Object.defineProperty(t,"__esModule",{value:!0}),t}({},Vue); +var VueMeta=function(t,e,r,n,o,a,i,u,c,f){"use strict";function l(t){return t&&"object"==typeof t&&"default"in t?t.default:t}var s=l(e),v=l(r),d=l(n),y=l(o),p=l(a),m=l(i),h=l(c),b=l(f),g=function(t,e){return function(r,n){var o=-1;if(n.reduce((function(e,r,n){var a=t(e,r);return a!==e?(o=n,a):e}),e),o>-1)return r[o]}},A=g((function(t,e){var r=e.depth;return!t||r>t?r:t})),S=Object.freeze({__proto__:null,setup:function(t){var e=0;if(t.vm){var r=t.vm;do{r.parent&&(e++,r=r.parent)}while(r&&r.parent&&r!==r.root)}t.depth=e},resolve:A}),w={body:{tag:"script",to:"body"},base:{valueAttribute:"href"},charset:{tag:"meta",nameless:!0,valueAttribute:"charset"},description:{tag:"meta"},og:{group:!0,namespacedAttribute:!0,tag:"meta",keyAttribute:"property"},twitter:{group:!0,namespacedAttribute:!0,tag:"meta"},htmlAttrs:{attributesFor:"html"},headAttrs:{attributesFor:"head"},bodyAttrs:{attributesFor:"body"}},j={title:{attributes:!1},base:{contentAsAttribute:!0,attributes:["href","target"]},meta:{contentAsAttribute:!0,keyAttribute:"name",attributes:["content","name","http-equiv","charset"]},link:{contentAsAttribute:!0,attributes:["href","crossorigin","rel","media","integrity","hreflang","type","referrerpolicy","sizes","imagesrcset","imagesizes","as","color"]},style:{attributes:["media"]},script:{attributes:["src","type","nomodule","async","defer","crossorigin","integrity","referrerpolicy"]},noscript:{attributes:!1}};function O(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(!t)return;if("string"==typeof t)return k(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);"Object"===r&&t.constructor&&(r=t.constructor.name);if("Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return k(t,e)}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function k(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r"function"==typeof t,M=t=>"string"==typeof t,P=t=>null!==t&&"object"==typeof t,R=Object.prototype.toString,E=t=>"[object Object]"===R.call(t);var N=Symbol("kIsProxy"),_=Symbol("kProxySources"),U=Symbol("kProxyTarget"),T=Symbol("kResolveContext");function $(t){if(I(t))return t.map($);if(P(t)){var e={};for(var r in t)e[r]="context"===r?t[r]:$(t[r]);return e}return t}function F(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(!t)return;if("string"==typeof t)return D(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);"Object"===r&&t.constructor&&(r=t.constructor.name);if("Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return D(t,e)}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function D(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function L(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1&&void 0!==arguments[1]&&arguments[1],n=function(){try{throw new Error("DEBUG")}catch(o){for(var t=arguments.length,r=new Array(t),n=0;n1?r-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2?arguments[2]:void 0,o=arguments.length>3?arguments[3]:void 0,a=!n&&!o;if(a&&(n=e.active,o=e.sources,r.length))for(var i=function(t){var e=r[t];if(!n||!n[e])return console.error("recompute: segment ".concat(e," not found on target"),r,n),{v:void 0};n=n[e],o=o.map((function(t){return t[e]})).filter(Boolean)},u=0;u=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function H(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r3&&void 0!==arguments[3]?arguments[3]:[],o=W(t,r,n),a=u.markRaw(new Proxy(e,o));return!n.length&&t.sources&&t.sources.push(a),a},W=function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return{get:function(n,o,a){if(o===N)return!0;if(o===_)return t.sources;if(o===U)return n;if(o===T)return e;var i=Reflect.get(n,o,a);if(!P(i))return i;if(!i[N]){var u=[].concat(p(r),[o]);i=J(t,i,e,u),Reflect.set(n,o,i)}return i},set:function(e,n,o){var a=Reflect.set(e,n,o);if(a){var i,u,c=I(e),f=!1,l=t.sources,s=t.active,v=0,d=V(r);try{for(d.s();!(u=d.n()).done;){var y=u.value;if(l=z(l,y),c&&v===r.length-1){i=y;break}I(s)&&(f=!0),s=s[y],v++}}catch(t){d.e(t)}finally{d.f()}if(f)return G(t),a;if(E(o))return G(t,r),a;var p,m=[];c?(p=l,m=l.map((function(t){return t[T]}))):p=z(l,n,(function(t){return m.push(t[T])}));var h=t.resolve(p,m,s,n,r);E(h)&&(h=$(h)),c&&i?s[i]=h:s[n]=h}return a},deleteProperty:function(e,n){var o=Reflect.deleteProperty(e,n);if(o){var a,i,u=I(e),c=t.sources,f=t.active,l=0,s=V(r);try{var v=function(){var t=i.value;if(c=c.map((function(e){return e&&e[t]})),u&&l===r.length-1)return a=t,"break";f=f[t],l++};for(s.s();!(i=s.n()).done;){if("break"===v())break}}catch(t){s.e(t)}finally{s.f()}if(c.some((function(t){return t&&n in t}))){var d,y=[];u?(d=c,y=c.map((function(t){return t[T]}))):d=z(c,n,(function(t){return y.push(t[T])}));var p=t.resolve(d,y,f,n,r);E(p)&&(p=$(p)),u&&a?f[a]=p:f[n]=p}else delete f[n]}return o}}};function K(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function Q(t){for(var e=1;e=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function Y(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r3&&void 0!==arguments[3]?arguments[3]:{},o=arguments.length>4?arguments[4]:void 0,a=["content","json","rawContent"],i=function(t){return C([f,n.tag],t)};if(I(r))return r.map((function(r){return et(t,e,r,n,o)})).filter(Boolean).flat();var c=r.tag,f=void 0===c?n.tag||e:c,l="",s=!1,v=!1;if(M(r))l=r;else if(r.children&&I(r.children))s=!0,l=r.children.map((function(r){var a=et(t,e,r,n,o);return I(a)?a.map((function(t){return t.vnode})):a&&a.vnode}));else{var d,y=0,p=X(a);try{for(p.s();!(d=p.n()).done;){var m=d.value;if(!l&&r[m]){l=1===y?JSON.stringify(r[m]):r[m],v=y>1;break}y++}}catch(t){p.e(t)}finally{p.f()}}var g=o&&o.fullName||e,A=o&&o.slotName||e,S=r.attrs;if(S||"object"!==h(r))S||(S={});else{delete(S=Q({},r)).tag,delete S.children,delete S.to;var w,j=X(a);try{for(j.s();!(w=j.n()).done;){var O=w.value;delete S[O]}}catch(t){j.e(t)}finally{j.f()}}if(s)l=rt(t,A,l,r);else{var k=!!i("contentAsAttribute"),x=n.valueAttribute;if(!x&&k){var P=i("attributes"),R=b(P,1),E=R[0];x=M(k)?k:E}if(x){var N=n.nameless;if(!N){var _=n.keyAttribute||i("keyAttribute");_&&(S[_]=g)}S[x]=rt(t,A,S[x]||l,o),l=""}else l=rt(t,A,l,r)}var U=o&&o.tagNamespace?"".concat(o.tagNamespace,":").concat(f):f;if("title"!==U||t.isSSR){v&&l&&(S.innerHTML=l);var T=u.h(U,S,l||void 0);return{to:r.to,vnode:T}}document.title=l}function rt(t,e,r,n){var o=t.metainfo,a=t.slots,i=a&&a[e];if(!i||!x(i))return r;var u={content:r,metainfo:o};n&&n.group&&(u[n.group]=n.data);var c=i(u);if(c&&c.length){var f=c[0].children;return f?f.toString():""}return r}var nt="function"==typeof Symbol&&"symbol"===h(Symbol.toStringTag),ot=function(t){return nt?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t}("meta_active");function at(t,e,r){for(var n in e)n in r?P(t[n])?at(t[n],e[n],r[n]):e[n]!==r[n]&&(t[n]=e[n]):t[n]=e[n];for(var o in r)e&&o in e||delete t[o]}function it(t){if(t||(t=u.getCurrentInstance()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function ut(t,e){var r=u.getCurrentInstance()||void 0;if(!e&&r&&(e=it(r)),!e)throw new Error("No manager or current instance");u.isProxy(t)&&(u.watch(t,(function(t,e){at(n.meta,t,e)})),t=t.value);var n=e.addMeta(t,r);return n}var ct=u.defineComponent({name:"Metainfo",inheritAttrs:!1,setup:function(t,e){var r=e.slots;return function(){var t=it();if(t)return t.render({slots:r})}}});function ft(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(!t)return;if("string"==typeof t)return lt(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);"Object"===r&&t.constructor&&(r=t.constructor.name);if("Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return lt(t,e)}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}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 a,i=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){u=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function lt(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r0&&void 0!==arguments[0]?arguments[0]:{},e=t.slots,r=this.target.context.active,n=this.isSSR;if(!n&&!this.ssrCleanedUp){this.ssrCleanedUp=!0;var o=function(){var t=document.querySelectorAll("[".concat(st,"]"));t&&t.length&&t.forEach((function(t){return t.parentNode&&t.parentNode.removeChild(t)}))};"loading"===document.readyState?window.addEventListener("DOMContentLoaded",o,{once:!0}):o()}var a={};for(var i in r){var c=this.config[i]||{},f=tt({isSSR:n,metainfo:r,slots:e},i,r[i],c);if(f){I(f)||(f=[f]);var l="base"!==i&&r[i].to;!l&&"to"in c&&(l=c.to),!l&&"attributesFor"in c&&(l=i);var s,v=ft(f);try{for(v.s();!(s=v.n()).done;){var d=s.value,y=d.to,p=d.vnode;vt(this.isSSR,a,y||l||"head",p)}}catch(t){v.e(t)}finally{v.f()}}}if(e)for(var m in e){var h="default"===m?"head":m;if("head"===h||"body"===h){var b=e[m];x(b)&&vt(this.isSSR,a,h,b({metainfo:r}))}}return Object.keys(a).map((function(t){return u.h(u.Teleport,{to:t},a[t])}))}}]),t}();y(dt,"create",(function(t,e,r){var n=function(t,e){var r=[],n={active:e,resolve:t,sources:r},o=function(){return G(n)};return{context:n,compute:o,addSource:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],a=J(n,t,e||{});return r&&o(),a},delSource:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=r.findIndex((function(e){return e===t||e[U]===t}));return n>-1&&(r.splice(n,1),e&&o(),!0)}}}((function(t,e,n,o,a){return x(r)?r(t,e,n,o,a):r.resolve(t,e,n,o,a)}),u.reactive({}));return new dt(t,e,n,r)}));var yt={keyName:"metaInfo"},pt=function(t){return{created:function(){var e=u.getCurrentInstance();if(null!=e&&e.type&&t.keyName in e.type){var r=e.type[t.keyName];if(x(r))ut(u.computed(r.bind(this)));else ut(r)}}}};return t.createMetaManager=function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1?arguments[1]:void 0,r=arguments.length>2?arguments[2]:void 0;return dt.create(t,e||w,r||S)},t.deepestResolver=S,t.defaultConfig=w,t.getCurrentManager=it,t.plugin=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=Object.assign({},yt,e);t.mixin(pt(r))},t.resolveOption=g,t.useActiveMeta=function(){return u.inject(ot)},t.useMeta=ut,Object.defineProperty(t,"__esModule",{value:!0}),t}({},_asyncToGenerator,_classCallCheck,_createClass,_defineProperty,_toConsumableArray,_regeneratorRuntime,Vue,_typeof,_slicedToArray); diff --git a/package.json b/package.json index 7dd1410f..b5ba572d 100644 --- a/package.json +++ b/package.json @@ -58,9 +58,13 @@ "devDependencies": { "@babel/core": "^7.14.8", "@babel/plugin-transform-modules-commonjs": "^7.14.5", + "@babel/plugin-transform-runtime": "^7.18.9", + "@babel/preset-env": "^7.18.9", "@babel/preset-typescript": "^7.14.5", + "@babel/runtime": "^7.18.9", "@nuxtjs/eslint-config-typescript": "^6.0.1", "@rollup/plugin-alias": "^3.1.5", + "@rollup/plugin-babel": "^5.3.1", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-replace": "^3.0.0",