From 5520faf79b1172f2128fca784fd9c4e6e2c0d03d Mon Sep 17 00:00:00 2001 From: pimlie Date: Sun, 4 Apr 2021 23:06:23 +0000 Subject: [PATCH] chore(release): 3.0.0-alpha.3 --- CHANGELOG.md | 17 ++++++++++ dist/vue-meta.cjs.js | 54 +++++++++++++++++++------------- dist/vue-meta.cjs.prod.js | 51 +++++++++++++++++------------- dist/vue-meta.d.ts | 47 +++++++++++++++++---------- dist/vue-meta.esm-browser.js | 39 ++++++++++++----------- dist/vue-meta.esm-browser.min.js | 4 +-- dist/vue-meta.esm-bundler.js | 50 ++++++++++++++--------------- dist/vue-meta.global.js | 39 ++++++++++++----------- dist/vue-meta.global.min.js | 4 +-- package.json | 2 +- 10 files changed, 181 insertions(+), 126 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84d132a7..a613f933 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [3.0.0-alpha.3](https://github.com/nuxt/vue-meta/compare/v3.0.0-alpha.2...v3.0.0-alpha.3) (2021-04-04) + + +### Features + +* add fully static / client-only example ([c6c3b47](https://github.com/nuxt/vue-meta/commit/c6c3b4758664b0b7ea2487ed785128416d0905b5)) +* make createMetaManager util args optional (use defaults) ([89d7f58](https://github.com/nuxt/vue-meta/commit/89d7f584910da78a6af6bc700dde61a8a1625658)) + + +### Bug Fixes + +* dont call clean before starting dev server ([683ea9c](https://github.com/nuxt/vue-meta/commit/683ea9c0765dea40b98093d6946cabc0369d79c2)) +* fix/improve resolver types ([fcb47a9](https://github.com/nuxt/vue-meta/commit/fcb47a9d5f106704f1e187154b5691939130f630)) +* only match vue-meta in jiti alias ([2b8c5e8](https://github.com/nuxt/vue-meta/commit/2b8c5e8866e54d9fd784a6f1bb3733d572aaa8af)) +* replace node-env in rollup config ([ed6ba9f](https://github.com/nuxt/vue-meta/commit/ed6ba9fa942869e9c10dbd1df251381451117e74)) +* use dynamic import for vue server-renderer ([8e2fed1](https://github.com/nuxt/vue-meta/commit/8e2fed1525f1c8594ab4bf4360ffb4af11ea8ddb)) + ## [3.0.0-alpha.2](https://github.com/nuxt/vue-meta/compare/v3.0.0-alpha.1...v3.0.0-alpha.2) (2021-02-28) diff --git a/dist/vue-meta.cjs.js b/dist/vue-meta.cjs.js index 9ff1757d..adf897a9 100644 --- a/dist/vue-meta.cjs.js +++ b/dist/vue-meta.cjs.js @@ -1,5 +1,5 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - All the amazing contributors @@ -12,7 +12,19 @@ Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); -const resolveOption = predicament => (options, contexts) => { +function _interopNamespace(e) { + if (e && e.__esModule) return e; + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + n[k] = e[k]; + }); + } + n['default'] = e; + return Object.freeze(n); +} + +const resolveOption = (predicament, initialValue) => (options, contexts) => { let resolvedIndex = -1; contexts.reduce((acc, context, index) => { const retval = predicament(acc, context); @@ -21,7 +33,7 @@ const resolveOption = predicament => (options, contexts) => { return retval; } return acc; - }, undefined); + }, initialValue); if (resolvedIndex > -1) { return options[resolvedIndex]; } @@ -40,14 +52,15 @@ function setup(context) { } context.depth = depth; } -const resolve = resolveOption((acc, context) => { +const resolve = resolveOption((currentValue, context) => { const { depth } = context; - if (!acc || depth > acc) { - return acc; + if (!currentValue || depth > currentValue) { + return depth; } + return currentValue; }); -var deepest = /*#__PURE__*/Object.freeze({ +var defaultResolver = /*#__PURE__*/Object.freeze({ __proto__: null, setup: setup, resolve: resolve @@ -161,10 +174,9 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ -(process.env.NODE_ENV !== 'production') - ? Object.freeze({}) - : {}; -(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; +Object.freeze({}) + ; +Object.freeze([]) ; const isArray = Array.isArray; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; @@ -252,6 +264,7 @@ const recompute = (context, sources, target, path = []) => { } for (const key of keys) { // This assumes consistent types usages for keys across sources + // @ts-ignore if (isPlainObject(sources[0][key])) { if (!target[key]) { target[key] = {}; @@ -259,6 +272,7 @@ const recompute = (context, sources, target, path = []) => { const keySources = []; for (const source of sources) { if (key in source) { + // @ts-ignore keySources.push(source[key]); } } @@ -266,6 +280,7 @@ const recompute = (context, sources, target, path = []) => { 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] = []; } @@ -309,7 +324,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ if (!value[IS_PROXY]) { const keyPath = [...pathSegments, key]; value = createProxy(context, value, resolveContext, keyPath); - target[key] = value; + Reflect.set(target, key, value); } return value; }, @@ -381,6 +396,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ let active = context.active; let index = 0; for (const segment of pathSegments) { + // @ts-ignore proxies = proxies.map(proxy => proxy[segment]); if (isArrayItem && index === pathSegments.length - 1) { activeSegmentKey = segment; @@ -421,11 +437,8 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ } }); -const createMergedObject = (resolve, active = {}) => { +const createMergedObject = (resolve, active) => { const sources = []; - if (!active) { - active = {}; - } const context = { active, resolve, @@ -443,7 +456,7 @@ const createMergedObject = (resolve, active = {}) => { return proxy; }, delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(src => src === sourceOrProxy || src[PROXY_TARGET] === sourceOrProxy); + const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); if (index > -1) { sources.splice(index, 1); if (recompute) { @@ -727,7 +740,7 @@ function addVnode(teleports, to, vnodes) { } teleports[to].push(...nodes); } -const createMetaManager = (config, resolver) => MetaManager.create(config, resolver); +const createMetaManager = (config, resolver) => MetaManager.create(config || defaultConfig, resolver || defaultResolver); class MetaManager { constructor(config, target, resolver) { this.ssrCleanedUp = false; @@ -850,9 +863,8 @@ MetaManager.create = (config, resolver) => { return manager; }; -// rollup doesnt like an import as it cant find the export so use require -const { renderToString } = require('@vue/server-renderer'); async function renderToStringWithMeta(app) { + const { renderToString } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@vue/server-renderer')); }); const ctx = {}; const html = await renderToString(app, ctx); // TODO: better way of determining whether meta was rendered with the component or not @@ -872,7 +884,7 @@ async function renderToStringWithMeta(app) { } exports.createMetaManager = createMetaManager; -exports.deepestResolver = deepest; +exports.deepestResolver = defaultResolver; exports.defaultConfig = defaultConfig; exports.getCurrentManager = getCurrentManager; exports.renderToStringWithMeta = renderToStringWithMeta; diff --git a/dist/vue-meta.cjs.prod.js b/dist/vue-meta.cjs.prod.js index 8ba63d35..94082f6f 100644 --- a/dist/vue-meta.cjs.prod.js +++ b/dist/vue-meta.cjs.prod.js @@ -1,5 +1,5 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - All the amazing contributors @@ -12,7 +12,19 @@ Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); -const resolveOption = predicament => (options, contexts) => { +function _interopNamespace(e) { + if (e && e.__esModule) return e; + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + n[k] = e[k]; + }); + } + n['default'] = e; + return Object.freeze(n); +} + +const resolveOption = (predicament, initialValue) => (options, contexts) => { let resolvedIndex = -1; contexts.reduce((acc, context, index) => { const retval = predicament(acc, context); @@ -21,7 +33,7 @@ const resolveOption = predicament => (options, contexts) => { return retval; } return acc; - }, undefined); + }, initialValue); if (resolvedIndex > -1) { return options[resolvedIndex]; } @@ -40,14 +52,15 @@ function setup(context) { } context.depth = depth; } -const resolve = resolveOption((acc, context) => { +const resolve = resolveOption((currentValue, context) => { const { depth } = context; - if (!acc || depth > acc) { - return acc; + if (!currentValue || depth > currentValue) { + return depth; } + return currentValue; }); -var deepest = /*#__PURE__*/Object.freeze({ +var defaultResolver = /*#__PURE__*/Object.freeze({ __proto__: null, setup: setup, resolve: resolve @@ -161,10 +174,6 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ -(process.env.NODE_ENV !== 'production') - ? Object.freeze({}) - : {}; -(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; const isArray = Array.isArray; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; @@ -252,6 +261,7 @@ const recompute = (context, sources, target, path = []) => { } for (const key of keys) { // This assumes consistent types usages for keys across sources + // @ts-ignore if (isPlainObject(sources[0][key])) { if (!target[key]) { target[key] = {}; @@ -259,6 +269,7 @@ const recompute = (context, sources, target, path = []) => { const keySources = []; for (const source of sources) { if (key in source) { + // @ts-ignore keySources.push(source[key]); } } @@ -266,6 +277,7 @@ const recompute = (context, sources, target, path = []) => { 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] = []; } @@ -309,7 +321,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ if (!value[IS_PROXY]) { const keyPath = [...pathSegments, key]; value = createProxy(context, value, resolveContext, keyPath); - target[key] = value; + Reflect.set(target, key, value); } return value; }, @@ -381,6 +393,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ let active = context.active; let index = 0; for (const segment of pathSegments) { + // @ts-ignore proxies = proxies.map(proxy => proxy[segment]); if (isArrayItem && index === pathSegments.length - 1) { activeSegmentKey = segment; @@ -421,11 +434,8 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ } }); -const createMergedObject = (resolve, active = {}) => { +const createMergedObject = (resolve, active) => { const sources = []; - if (!active) { - active = {}; - } const context = { active, resolve, @@ -443,7 +453,7 @@ const createMergedObject = (resolve, active = {}) => { return proxy; }, delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(src => src === sourceOrProxy || src[PROXY_TARGET] === sourceOrProxy); + const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); if (index > -1) { sources.splice(index, 1); if (recompute) { @@ -723,7 +733,7 @@ function addVnode(teleports, to, vnodes) { } teleports[to].push(...nodes); } -const createMetaManager = (config, resolver) => MetaManager.create(config, resolver); +const createMetaManager = (config, resolver) => MetaManager.create(config || defaultConfig, resolver || defaultResolver); class MetaManager { constructor(config, target, resolver) { this.ssrCleanedUp = false; @@ -846,9 +856,8 @@ MetaManager.create = (config, resolver) => { return manager; }; -// rollup doesnt like an import as it cant find the export so use require -const { renderToString } = require('@vue/server-renderer'); async function renderToStringWithMeta(app) { + const { renderToString } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@vue/server-renderer')); }); const ctx = {}; const html = await renderToString(app, ctx); // TODO: better way of determining whether meta was rendered with the component or not @@ -868,7 +877,7 @@ async function renderToStringWithMeta(app) { } exports.createMetaManager = createMetaManager; -exports.deepestResolver = deepest; +exports.deepestResolver = defaultResolver; exports.defaultConfig = defaultConfig; exports.getCurrentManager = getCurrentManager; exports.renderToStringWithMeta = renderToStringWithMeta; diff --git a/dist/vue-meta.d.ts b/dist/vue-meta.d.ts index 737382a8..a5d00d29 100644 --- a/dist/vue-meta.d.ts +++ b/dist/vue-meta.d.ts @@ -1,36 +1,49 @@ import { App, ComponentInternalInstance, Slots, VNode } from 'vue'; import { SSRContext } from '@vue/server-renderer'; -declare type MergeSource = { - [key: string]: any; +declare const IS_PROXY: unique symbol; +declare const PROXY_SOURCES: unique symbol; +declare const PROXY_TARGET: unique symbol; +declare const RESOLVE_CONTEXT: unique symbol; + +interface ResolveContext { +} +declare type MergeSource = { + [K in keyof T]: T[K]; +} & { + [IS_PROXY]: boolean; + [PROXY_SOURCES]: MergeSource[]; + [PROXY_TARGET]: MergeSource; + [RESOLVE_CONTEXT]: ResolveContext; }; declare type MergedObjectValue = boolean | number | string | MergedObject | any; declare type MergedObject = { [key: string]: MergedObjectValue; }; declare type PathSegments = Array; -declare type ResolveContext = {}; -declare type ResolveMethod = (options: Array, contexts: Array, active: MergedObjectValue, key: string | number | symbol, pathSegments: PathSegments) => MergedObjectValue; -declare type MergeContext = { +interface ResolveMethod { + (options: Array, contexts: Array, active: MergedObjectValue, key: string | number | symbol, pathSegments: PathSegments): MergedObjectValue; +} +declare type MergeContext = { resolve: ResolveMethod; active: MergedObject; - sources: Array; + sources: MergeSource[]; }; -declare type MergedObjectBuilder = { - context: MergeContext; +declare type MergedObjectBuilder = { + context: MergeContext; compute: () => void; - addSource: (source: MergeSource, resolveContext: ResolveContext | undefined, recompute?: Boolean) => any; - delSource: (sourceOrProxy: MergeSource, recompute?: boolean) => boolean; + addSource: (source: T, resolveContext?: ResolveContext, recompute?: Boolean) => any; + delSource: (sourceOrProxy: T | MergeSource, recompute?: boolean) => boolean; }; declare type createMetaManagerMethod = (config: MetaConfig, resolver: MetaResolver | ResolveMethod) => MetaManager; -declare const createMetaManager: createMetaManagerMethod; +declare const createMetaManager: (config?: MetaConfig | undefined, resolver?: MetaResolver | undefined) => MetaManager; declare class MetaManager { config: MetaConfig; - target: MergedObjectBuilder; + target: MergedObjectBuilder; resolver?: MetaResolverSetup; ssrCleanedUp: boolean; - constructor(config: MetaConfig, target: MergedObjectBuilder, resolver: MetaResolver | ResolveMethod); + constructor(config: MetaConfig, target: MergedObjectBuilder, resolver: MetaResolver | ResolveMethod); static create: createMetaManagerMethod; install(app: App): void; addMeta(metadata: MetaSource, vm?: ComponentInternalInstance): MetaProxy; @@ -173,7 +186,7 @@ declare type MergeResolveContextDeepest = MetaResolveContext & { depth: number; }; declare function setup(context: MergeResolveContextDeepest): void; -declare const resolve: ResolveMethod; +declare const resolve: ResolveMethod; declare const deepest_d_setup: typeof setup; declare const deepest_d_resolve: typeof resolve; @@ -186,8 +199,10 @@ declare namespace deepest_d { declare const defaultConfig: MetaConfig; -declare type ResolveOptionReducer = (accumulator: any, context: ResolveContext) => ResolveMethod; -declare const resolveOption: (predicament: ResolveOptionReducer) => ResolveMethod; +interface ResolveOptionPredicament { + (currentValue: T | undefined, context: U): T; +} +declare const resolveOption: (predicament: ResolveOptionPredicament, initialValue?: T | undefined) => ResolveMethod; declare function renderToStringWithMeta(app: App): Promise<[string, SSRContext]>; diff --git a/dist/vue-meta.esm-browser.js b/dist/vue-meta.esm-browser.js index aa0f92d5..c672ef52 100644 --- a/dist/vue-meta.esm-browser.js +++ b/dist/vue-meta.esm-browser.js @@ -1,5 +1,5 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - All the amazing contributors @@ -8,7 +8,7 @@ import { markRaw, h, getCurrentInstance, isProxy, watch, inject, defineComponent, reactive, onUnmounted, Teleport, Comment } from 'vue'; -const resolveOption = predicament => (options, contexts) => { +const resolveOption = (predicament, initialValue) => (options, contexts) => { let resolvedIndex = -1; contexts.reduce((acc, context, index) => { const retval = predicament(acc, context); @@ -17,7 +17,7 @@ const resolveOption = predicament => (options, contexts) => { return retval; } return acc; - }, undefined); + }, initialValue); if (resolvedIndex > -1) { return options[resolvedIndex]; } @@ -36,14 +36,15 @@ function setup(context) { } context.depth = depth; } -const resolve = resolveOption((acc, context) => { +const resolve = resolveOption((currentValue, context) => { const { depth } = context; - if (!acc || depth > acc) { - return acc; + if (!currentValue || depth > currentValue) { + return depth; } + return currentValue; }); -var deepest = /*#__PURE__*/Object.freeze({ +var defaultResolver = /*#__PURE__*/Object.freeze({ __proto__: null, setup: setup, resolve: resolve @@ -157,10 +158,9 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ -(process.env.NODE_ENV !== 'production') - ? Object.freeze({}) - : {}; -(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; +Object.freeze({}) + ; +Object.freeze([]) ; const isArray = Array.isArray; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; @@ -248,6 +248,7 @@ const recompute = (context, sources, target, path = []) => { } for (const key of keys) { // This assumes consistent types usages for keys across sources + // @ts-ignore if (isPlainObject(sources[0][key])) { if (!target[key]) { target[key] = {}; @@ -255,6 +256,7 @@ const recompute = (context, sources, target, path = []) => { const keySources = []; for (const source of sources) { if (key in source) { + // @ts-ignore keySources.push(source[key]); } } @@ -262,6 +264,7 @@ const recompute = (context, sources, target, path = []) => { 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] = []; } @@ -305,7 +308,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ if (!value[IS_PROXY]) { const keyPath = [...pathSegments, key]; value = createProxy(context, value, resolveContext, keyPath); - target[key] = value; + Reflect.set(target, key, value); } return value; }, @@ -377,6 +380,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ let active = context.active; let index = 0; for (const segment of pathSegments) { + // @ts-ignore proxies = proxies.map(proxy => proxy[segment]); if (isArrayItem && index === pathSegments.length - 1) { activeSegmentKey = segment; @@ -417,11 +421,8 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ } }); -const createMergedObject = (resolve, active = {}) => { +const createMergedObject = (resolve, active) => { const sources = []; - if (!active) { - active = {}; - } const context = { active, resolve, @@ -439,7 +440,7 @@ const createMergedObject = (resolve, active = {}) => { return proxy; }, delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(src => src === sourceOrProxy || src[PROXY_TARGET] === sourceOrProxy); + const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); if (index > -1) { sources.splice(index, 1); if (recompute) { @@ -745,7 +746,7 @@ function addVnode(teleports, to, vnodes) { } teleports[to].push(...nodes); } -const createMetaManager = (config, resolver) => MetaManager.create(config, resolver); +const createMetaManager = (config, resolver) => MetaManager.create(config || defaultConfig, resolver || defaultResolver); class MetaManager { constructor(config, target, resolver) { this.ssrCleanedUp = false; @@ -882,4 +883,4 @@ MetaManager.create = (config, resolver) => { return manager; }; -export { createMetaManager, deepest as deepestResolver, defaultConfig, getCurrentManager, resolveOption, useActiveMeta, useMeta }; +export { createMetaManager, defaultResolver as deepestResolver, defaultConfig, getCurrentManager, resolveOption, useActiveMeta, useMeta }; diff --git a/dist/vue-meta.esm-browser.min.js b/dist/vue-meta.esm-browser.min.js index 3081302b..f8acda95 100644 --- a/dist/vue-meta.esm-browser.min.js +++ b/dist/vue-meta.esm-browser.min.js @@ -1,8 +1,8 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - 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}from"vue";const f=t=>(e,o)=>{let r=-1;if(o.reduce(((e,o,n)=>{const s=t(e,o);return s!==e?(r=n,s):e}),void 0),r>-1)return e[r]};const d=f(((t,e)=>{const{depth:o}=e;if(!t||o>t)return t}));var p=Object.freeze({__proto__:null,setup:function(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:d});const m={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"}},b={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}};"production"===process.env.NODE_ENV||Object.freeze({}),"production"===process.env.NODE_ENV||Object.freeze([]);const h=Array.isArray,y=t=>"function"==typeof t,g=t=>"string"==typeof t,v=t=>null!==t&&"object"==typeof t,A=Object.prototype.toString,S=t=>"[object Object]"===A.call(t),N=Symbol("kIsProxy"),k=Symbol("kProxySources"),w=Symbol("kProxyTarget"),O=Symbol("kResolveContext");function j(t){if(h(t))return t.map(j);if(v(t)){const e={};for(const o in t)e[o]="context"===o?t[o]:j(t[o]);return e}return t}const x=(t,e,o)=>{const r=[];for(const n of t)e in n&&(r.push(n[e]),o&&o(n));return r},$=(t,e,o,r=[])=>{if(r.length||(o||(o=t.active),e||(e=t.sources)),!o||!e)return;const n=((t,...e)=>{const o=t?Object.keys(t):[];if(e)for(const t of e)if(t&&v(t))for(const e in t)o.includes(e)||o.push(e);return o})(...e),s=Object.keys(o);for(const t of s)n.includes(t)||delete o[t];for(const s of n){if(S(e[0][s])){o[s]||(o[s]={});const n=[];for(const t of e)s in t&&n.push(t[s]);$(t,n,o[s],[...r,s]);continue}!o[s]&&h(e[0][s])&&(o[s]=[]);const n=[],i=x(e,s,(t=>n.push(t[O])));let c=t.resolve(i,n,o[s],s,r);S(c)&&(c=j(c)),o[s]=c}},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===k)return t.sources;if(n===w)return r;if(n===O)return e;let i=Reflect.get(r,n,s);if(!v(i))return i;if(!i[N]){const s=[...o,n];i=P(t,i,e,s),r[n]=i}return i},set:(e,r,n)=>{const s=Reflect.set(e,r,n);if(s){const n=h(e);let i,c=!1,{sources:a,active:u}=t,l=0;for(const t of o){if(a=x(a,t),n&&l===o.length-1){i=t;break}h(u)&&(c=!0),u=u[t],l++}if(c)return $(t),s;let f,d=[];n?(f=a,d=a.map((t=>t[O]))):f=x(a,r,(t=>d.push(t[O])));let p=t.resolve(f,d,u,r,o);S(p)&&(p=j(p)),n&&i?u[i]=p:u[r]=p}return s},deleteProperty:(e,r)=>{const n=Reflect.deleteProperty(e,r);if(n){const n=h(e);let s,i=t.sources,c=t.active,a=0;for(const t of o){if(i=i.map((e=>e[t])),n&&a===o.length-1){s=t;break}c=c[t],a++}if(i.some((t=>r in t))){let e,a=[];n?(e=i,a=i.map((t=>t[O]))):e=x(i,r,(t=>a.push(t[O])));let u=t.resolve(e,a,c,r,o);S(u)&&(u=j(u)),n&&s?c[s]=u:c[r]=u}else delete c[r]}return n}}),E={};function M(t,e,o,r){return"attributesFor"in r?function(t,e,o,r){const{attributesFor:n}=r;if(!n)return;if(!E[n]){const[t,e]=Array.from(document.querySelectorAll(n));if(!t)return void console.error("Could not find element for selector",n,", won't render attributes");e&&console.warn("Found multiple elements for selector",n),E[n]={el:t,attrs:[]}}const{el:s,attrs:i}=E[n];for(const r in o){const n=_(t,`${e}(${r})`,o[r],o);s.setAttribute(r,n||""),i.includes(r)||i.push(r)}const c=i.filter((t=>!o[t]));for(const t of c)s.removeAttribute(t)}(t,e,o,r):"group"in r?function(t,e,o,r){if(h(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 F(t,e,o[n],r,s)})).flat()}(t,e,o,r):F(t,e,o,r)}function F(t,o,r,n={},s){const i=["content","json","rawContent"],c=t=>function(t,e){for(const o of t){const t=b[o];if(o&&t)return t[e]}}([a,n.tag],t);if(h(r))return r.map((e=>F(t,o,e,n,s))).flat();const{tag:a=n.tag||o}=r;let u="",l=!1,f=!1;if(g(r))u=r;else if(r.children&&h(r.children))l=!0,u=r.children.map((e=>{const r=F(t,o,e,n,s);return h(r)?r.map((({vnode:t})=>t)):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=_(t,p,u,r);else{const e=!!c("contentAsAttribute");let{valueAttribute:o}=n;if(!o&&e){const[t]=c("attributes");o=g(e)?e:t}if(o){const{nameless:e,keyAttribute:r}=n;e||r&&(m[r]=d),m[o]=_(t,p,m[o]||u,s),u=""}else u=_(t,p,u,r)}const y=s&&s.tagNamespace?`${s.tagNamespace}:${a}`:a;f&&u&&(m.innerHTML=u);const v=e(y,m,u||void 0);return{to:r.to,vnode:v}}function _({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 R="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,U=(t=>R?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function z(t){if(t||(t=o()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function L(t,e){const s=o()||void 0;if(!e&&s&&(e=z(s)),!e)throw new Error("No manager or current instance");r(t)&&(n(t,((t,e)=>{!function(t,e,o){for(const r in e)r in o?v(t[r])||e[r]!==o[r]&&(t[r]=e[r]):t[r]=e[r];for(const r in o)r in e||delete t[r]}(i.meta,t,e)})),t=t.value);const i=e.addMeta(t,s);return i}function q(){return s(U)}const D=i({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=z();if(t)return t.render({slots:e})}}),T=c({});function I(t,e,o){const r=h(o)?o:[o];r.forEach(((t,e)=>{t.type===l&&r.splice(e,1)})),t[e]||(t[e]=[]),t[e].push(...r)}const V=(t,e)=>H.create(t,e);class H{constructor(t,e,o){this.ssrCleanedUp=!1,this.config=t,this.target=e,o&&"setup"in o&&y(o.setup)&&(this.resolver=o)}install(t){t.component("Metainfo",D),t.config.globalProperties.$metaManager=this,t.provide(U,T)}addMeta(t,e){e||(e=o()||void 0);const r={removed:[]},n={vm:e};this.resolver&&this.resolver.setup(n);const s=this.target.addSource(t,n,!0),i=t=>this.unmount(!!t,s,r,e);return e&&a(i),{meta:s,onRemoved:t=>r.removed.push(t),unmount:i}}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}={}){this.ssrCleanedUp||(this.ssrCleanedUp=!0,window.addEventListener("DOMContentLoaded",(()=>{const t=document.querySelectorAll("[data-vm-ssr]");t&&t.length&&Array.from(t).forEach((t=>t.parentNode&&t.parentNode.removeChild(t)))})));const o={};for(const e in T){const r=this.config[e]||{};let n=M({metainfo:T,slots:t},e,T[e],r);if(!n)continue;h(n)||(n=[n]);let s="base"!==e&&T[e].to;!s&&"to"in r&&(s=r.to),!s&&"attributesFor"in r&&(s=e);for(const{to:t,vnode:e}of n)I(o,t||s||"head",e)}if(t)for(const e in t){const r="default"===e?"head":e;if("head"!==r&&"body"!==r)continue;const n=t[e];y(n)&&I(o,r,n({metainfo:T}))}return Object.keys(o).map((t=>e(u,{to:t},o[t])))}}H.create=(t,e)=>{const o=((t,e={})=>{const o=[];e||(e={});const 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[w]===t));return r>-1&&(o.splice(r,1),e&&n(),!0)}}})(((t,o,r,n,s)=>y(e)?e(t,o,r,n,s):e.resolve(t,o,r,n,s)),T);return new H(t,o,e)};export{V as createMetaManager,p as deepestResolver,m as defaultConfig,z as getCurrentManager,f as resolveOption,q as useActiveMeta,L as useMeta}; +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}from"vue";const f=(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]};const d=f(((t,e)=>{const{depth:o}=e;return!t||o>t?o:t}));var p=Object.freeze({__proto__:null,setup:function(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:d});const m={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"}},b={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 h=Array.isArray,y=t=>"function"==typeof t,g=t=>"string"==typeof t,v=t=>null!==t&&"object"==typeof t,A=Object.prototype.toString,S=t=>"[object Object]"===A.call(t),k=Symbol("kIsProxy"),w=Symbol("kProxySources"),j=Symbol("kProxyTarget"),N=Symbol("kResolveContext");function O(t){if(h(t))return t.map(O);if(v(t)){const e={};for(const o in t)e[o]="context"===o?t[o]:O(t[o]);return e}return t}const x=(t,e,o)=>{const r=[];for(const n of t)e in n&&(r.push(n[e]),o&&o(n));return r},$=(t,e,o,r=[])=>{if(r.length||(o||(o=t.active),e||(e=t.sources)),!o||!e)return;const n=((t,...e)=>{const o=t?Object.keys(t):[];if(e)for(const t of e)if(t&&v(t))for(const e in t)o.includes(e)||o.push(e);return o})(...e),s=Object.keys(o);for(const t of s)n.includes(t)||delete o[t];for(const s of n){if(S(e[0][s])){o[s]||(o[s]={});const n=[];for(const t of e)s in t&&n.push(t[s]);$(t,n,o[s],[...r,s]);continue}!o[s]&&h(e[0][s])&&(o[s]=[]);const n=[],i=x(e,s,(t=>n.push(t[N])));let c=t.resolve(i,n,o[s],s,r);S(c)&&(c=O(c)),o[s]=c}},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===k)return!0;if(n===w)return t.sources;if(n===j)return r;if(n===N)return e;let i=Reflect.get(r,n,s);if(!v(i))return i;if(!i[k]){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 n=h(e);let i,c=!1,{sources:a,active:u}=t,l=0;for(const t of o){if(a=x(a,t),n&&l===o.length-1){i=t;break}h(u)&&(c=!0),u=u[t],l++}if(c)return $(t),s;let f,d=[];n?(f=a,d=a.map((t=>t[N]))):f=x(a,r,(t=>d.push(t[N])));let p=t.resolve(f,d,u,r,o);S(p)&&(p=O(p)),n&&i?u[i]=p:u[r]=p}return s},deleteProperty:(e,r)=>{const n=Reflect.deleteProperty(e,r);if(n){const n=h(e);let s,i=t.sources,c=t.active,a=0;for(const t of o){if(i=i.map((e=>e[t])),n&&a===o.length-1){s=t;break}c=c[t],a++}if(i.some((t=>r in t))){let e,a=[];n?(e=i,a=i.map((t=>t[N]))):e=x(i,r,(t=>a.push(t[N])));let u=t.resolve(e,a,c,r,o);S(u)&&(u=O(u)),n&&s?c[s]=u:c[r]=u}else delete c[r]}return n}}),M={};function F(t,e,o,r){return"attributesFor"in r?function(t,e,o,r){const{attributesFor:n}=r;if(!n)return;if(!M[n]){const[t,e]=Array.from(document.querySelectorAll(n));if(!t)return void console.error("Could not find element for selector",n,", won't render attributes");e&&console.warn("Found multiple elements for selector",n),M[n]={el:t,attrs:[]}}const{el:s,attrs:i}=M[n];for(const r in o){const n=U(t,`${e}(${r})`,o[r],o);s.setAttribute(r,n||""),i.includes(r)||i.push(r)}const c=i.filter((t=>!o[t]));for(const t of c)s.removeAttribute(t)}(t,e,o,r):"group"in r?function(t,e,o,r){if(h(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 R(t,e,o[n],r,s)})).flat()}(t,e,o,r):R(t,e,o,r)}function R(t,o,r,n={},s){const i=["content","json","rawContent"],c=t=>function(t,e){for(const o of t){const t=b[o];if(o&&t)return t[e]}}([a,n.tag],t);if(h(r))return r.map((e=>R(t,o,e,n,s))).flat();const{tag:a=n.tag||o}=r;let u="",l=!1,f=!1;if(g(r))u=r;else if(r.children&&h(r.children))l=!0,u=r.children.map((e=>{const r=R(t,o,e,n,s);return h(r)?r.map((({vnode:t})=>t)):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=g(e)?e:t}if(o){const{nameless:e,keyAttribute:r}=n;e||r&&(m[r]=d),m[o]=U(t,p,m[o]||u,s),u=""}else u=U(t,p,u,r)}const y=s&&s.tagNamespace?`${s.tagNamespace}:${a}`:a;f&&u&&(m.innerHTML=u);const v=e(y,m,u||void 0);return{to:r.to,vnode:v}}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,E=(t=>z?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function _(t){if(t||(t=o()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function L(t,e){const s=o()||void 0;if(!e&&s&&(e=_(s)),!e)throw new Error("No manager or current instance");r(t)&&(n(t,((t,e)=>{!function(t,e,o){for(const r in e)r in o?v(t[r])||e[r]!==o[r]&&(t[r]=e[r]):t[r]=e[r];for(const r in o)r in e||delete t[r]}(i.meta,t,e)})),t=t.value);const i=e.addMeta(t,s);return i}function q(){return s(E)}const T=i({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=_();if(t)return t.render({slots:e})}}),I=c({});function D(t,e,o){const r=h(o)?o:[o];r.forEach(((t,e)=>{t.type===l&&r.splice(e,1)})),t[e]||(t[e]=[]),t[e].push(...r)}const H=(t,e)=>J.create(t||m,e||p);class J{constructor(t,e,o){this.ssrCleanedUp=!1,this.config=t,this.target=e,o&&"setup"in o&&y(o.setup)&&(this.resolver=o)}install(t){t.component("Metainfo",T),t.config.globalProperties.$metaManager=this,t.provide(E,I)}addMeta(t,e){e||(e=o()||void 0);const r={removed:[]},n={vm:e};this.resolver&&this.resolver.setup(n);const s=this.target.addSource(t,n,!0),i=t=>this.unmount(!!t,s,r,e);return e&&a(i),{meta:s,onRemoved:t=>r.removed.push(t),unmount:i}}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}={}){this.ssrCleanedUp||(this.ssrCleanedUp=!0,window.addEventListener("DOMContentLoaded",(()=>{const t=document.querySelectorAll("[data-vm-ssr]");t&&t.length&&Array.from(t).forEach((t=>t.parentNode&&t.parentNode.removeChild(t)))})));const o={};for(const e in I){const r=this.config[e]||{};let n=F({metainfo:I,slots:t},e,I[e],r);if(!n)continue;h(n)||(n=[n]);let s="base"!==e&&I[e].to;!s&&"to"in r&&(s=r.to),!s&&"attributesFor"in r&&(s=e);for(const{to:t,vnode:e}of n)D(o,t||s||"head",e)}if(t)for(const e in t){const r="default"===e?"head":e;if("head"!==r&&"body"!==r)continue;const n=t[e];y(n)&&D(o,r,n({metainfo:I}))}return Object.keys(o).map((t=>e(u,{to:t},o[t])))}}J.create=(t,e)=>{const o=((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[j]===t));return r>-1&&(o.splice(r,1),e&&n(),!0)}}})(((t,o,r,n,s)=>y(e)?e(t,o,r,n,s):e.resolve(t,o,r,n,s)),I);return new J(t,o,e)};export{H as createMetaManager,p as deepestResolver,m as defaultConfig,_ as getCurrentManager,f as resolveOption,q as useActiveMeta,L as useMeta}; diff --git a/dist/vue-meta.esm-bundler.js b/dist/vue-meta.esm-bundler.js index 2777647e..ef7f2a46 100644 --- a/dist/vue-meta.esm-bundler.js +++ b/dist/vue-meta.esm-bundler.js @@ -1,5 +1,5 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - All the amazing contributors @@ -8,7 +8,7 @@ import { markRaw, h, getCurrentInstance, isProxy, watch, inject, defineComponent, reactive, onUnmounted, Teleport } from 'vue'; -const resolveOption = predicament => (options, contexts) => { +const resolveOption = (predicament, initialValue) => (options, contexts) => { let resolvedIndex = -1; contexts.reduce((acc, context, index) => { const retval = predicament(acc, context); @@ -17,7 +17,7 @@ const resolveOption = predicament => (options, contexts) => { return retval; } return acc; - }, undefined); + }, initialValue); if (resolvedIndex > -1) { return options[resolvedIndex]; } @@ -36,14 +36,15 @@ function setup(context) { } context.depth = depth; } -const resolve = resolveOption((acc, context) => { +const resolve = resolveOption((currentValue, context) => { const { depth } = context; - if (!acc || depth > acc) { - return acc; + if (!currentValue || depth > currentValue) { + return depth; } + return currentValue; }); -var deepest = /*#__PURE__*/Object.freeze({ +var defaultResolver = /*#__PURE__*/Object.freeze({ __proto__: null, setup: setup, resolve: resolve @@ -157,10 +158,9 @@ function getTagConfigItem(tagOrName, key) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ -(process.env.NODE_ENV !== 'production') - ? Object.freeze({}) - : {}; -(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; +Object.freeze({}) + ; +Object.freeze([]) ; const isArray = Array.isArray; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; @@ -248,6 +248,7 @@ const recompute = (context, sources, target, path = []) => { } for (const key of keys) { // This assumes consistent types usages for keys across sources + // @ts-ignore if (isPlainObject(sources[0][key])) { if (!target[key]) { target[key] = {}; @@ -255,6 +256,7 @@ const recompute = (context, sources, target, path = []) => { const keySources = []; for (const source of sources) { if (key in source) { + // @ts-ignore keySources.push(source[key]); } } @@ -262,6 +264,7 @@ const recompute = (context, sources, target, path = []) => { 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] = []; } @@ -305,7 +308,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ if (!value[IS_PROXY]) { const keyPath = [...pathSegments, key]; value = createProxy(context, value, resolveContext, keyPath); - target[key] = value; + Reflect.set(target, key, value); } return value; }, @@ -377,6 +380,7 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ let active = context.active; let index = 0; for (const segment of pathSegments) { + // @ts-ignore proxies = proxies.map(proxy => proxy[segment]); if (isArrayItem && index === pathSegments.length - 1) { activeSegmentKey = segment; @@ -417,11 +421,8 @@ const createHandler = (context, resolveContext, pathSegments = []) => ({ } }); -const createMergedObject = (resolve, active = {}) => { +const createMergedObject = (resolve, active) => { const sources = []; - if (!active) { - active = {}; - } const context = { active, resolve, @@ -439,7 +440,7 @@ const createMergedObject = (resolve, active = {}) => { return proxy; }, delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(src => src === sourceOrProxy || src[PROXY_TARGET] === sourceOrProxy); + const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); if (index > -1) { sources.splice(index, 1); if (recompute) { @@ -465,7 +466,7 @@ function renderMeta(context, key, data, config) { function renderGroup(context, key, data, config) { // console.info('renderGroup', key, data, config) if (isArray(data)) { - if ((process.env.NODE_ENV !== 'production')) { + if (("development" !== 'production')) { // eslint-disable-next-line no-console console.warn('Specifying an array for group properties isnt supported'); } @@ -631,9 +632,9 @@ const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === const PolySymbol = (name) => // vm = vue meta hasSymbol - ? Symbol((process.env.NODE_ENV !== 'production') ? '[vue-meta]: ' + name : name) - : ((process.env.NODE_ENV !== 'production') ? '[vue-meta]: ' : '_vm_') + name; -const metaActiveKey = /*#__PURE__*/ PolySymbol((process.env.NODE_ENV !== 'production') ? 'meta_active' : 'ma'); + ? Symbol(("development" !== 'production') ? '[vue-meta]: ' + name : name) + : (("development" !== 'production') ? '[vue-meta]: ' : '_vm_') + name; +const metaActiveKey = /*#__PURE__*/ PolySymbol(("development" !== 'production') ? 'meta_active' : 'ma'); /** * Apply the differences between newSource & oldSource to target @@ -723,7 +724,7 @@ function addVnode(teleports, to, vnodes) { } teleports[to].push(...nodes); } -const createMetaManager = (config, resolver) => MetaManager.create(config, resolver); +const createMetaManager = (config, resolver) => MetaManager.create(config || defaultConfig, resolver || defaultResolver); class MetaManager { constructor(config, target, resolver) { this.ssrCleanedUp = false; @@ -846,9 +847,8 @@ MetaManager.create = (config, resolver) => { return manager; }; -// rollup doesnt like an import as it cant find the export so use require -const { renderToString } = require('@vue/server-renderer'); async function renderToStringWithMeta(app) { + const { renderToString } = await import('@vue/server-renderer'); const ctx = {}; const html = await renderToString(app, ctx); // TODO: better way of determining whether meta was rendered with the component or not @@ -867,4 +867,4 @@ async function renderToStringWithMeta(app) { return [html, ctx]; } -export { createMetaManager, deepest as deepestResolver, defaultConfig, getCurrentManager, renderToStringWithMeta, resolveOption, useActiveMeta, useMeta }; +export { createMetaManager, defaultResolver as deepestResolver, defaultConfig, getCurrentManager, renderToStringWithMeta, resolveOption, useActiveMeta, useMeta }; diff --git a/dist/vue-meta.global.js b/dist/vue-meta.global.js index 3ce1add4..2901e236 100644 --- a/dist/vue-meta.global.js +++ b/dist/vue-meta.global.js @@ -1,5 +1,5 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - All the amazing contributors @@ -9,7 +9,7 @@ var VueMeta = (function (exports, vue) { 'use strict'; - const resolveOption = predicament => (options, contexts) => { + const resolveOption = (predicament, initialValue) => (options, contexts) => { let resolvedIndex = -1; contexts.reduce((acc, context, index) => { const retval = predicament(acc, context); @@ -18,7 +18,7 @@ var VueMeta = (function (exports, vue) { return retval; } return acc; - }, undefined); + }, initialValue); if (resolvedIndex > -1) { return options[resolvedIndex]; } @@ -37,14 +37,15 @@ var VueMeta = (function (exports, vue) { } context.depth = depth; } - const resolve = resolveOption((acc, context) => { + const resolve = resolveOption((currentValue, context) => { const { depth } = context; - if (!acc || depth > acc) { - return acc; + if (!currentValue || depth > currentValue) { + return depth; } + return currentValue; }); - var deepest = /*#__PURE__*/Object.freeze({ + var defaultResolver = /*#__PURE__*/Object.freeze({ __proto__: null, setup: setup, resolve: resolve @@ -158,10 +159,9 @@ var VueMeta = (function (exports, vue) { * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ - (process.env.NODE_ENV !== 'production') - ? Object.freeze({}) - : {}; - (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; + Object.freeze({}) + ; + Object.freeze([]) ; const isArray = Array.isArray; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; @@ -249,6 +249,7 @@ var VueMeta = (function (exports, vue) { } for (const key of keys) { // This assumes consistent types usages for keys across sources + // @ts-ignore if (isPlainObject(sources[0][key])) { if (!target[key]) { target[key] = {}; @@ -256,6 +257,7 @@ var VueMeta = (function (exports, vue) { const keySources = []; for (const source of sources) { if (key in source) { + // @ts-ignore keySources.push(source[key]); } } @@ -263,6 +265,7 @@ var VueMeta = (function (exports, vue) { 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] = []; } @@ -306,7 +309,7 @@ var VueMeta = (function (exports, vue) { if (!value[IS_PROXY]) { const keyPath = [...pathSegments, key]; value = createProxy(context, value, resolveContext, keyPath); - target[key] = value; + Reflect.set(target, key, value); } return value; }, @@ -378,6 +381,7 @@ var VueMeta = (function (exports, vue) { let active = context.active; let index = 0; for (const segment of pathSegments) { + // @ts-ignore proxies = proxies.map(proxy => proxy[segment]); if (isArrayItem && index === pathSegments.length - 1) { activeSegmentKey = segment; @@ -418,11 +422,8 @@ var VueMeta = (function (exports, vue) { } }); - const createMergedObject = (resolve, active = {}) => { + const createMergedObject = (resolve, active) => { const sources = []; - if (!active) { - active = {}; - } const context = { active, resolve, @@ -440,7 +441,7 @@ var VueMeta = (function (exports, vue) { return proxy; }, delSource: (sourceOrProxy, recompute = true) => { - const index = sources.findIndex(src => src === sourceOrProxy || src[PROXY_TARGET] === sourceOrProxy); + const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy); if (index > -1) { sources.splice(index, 1); if (recompute) { @@ -746,7 +747,7 @@ var VueMeta = (function (exports, vue) { } teleports[to].push(...nodes); } - const createMetaManager = (config, resolver) => MetaManager.create(config, resolver); + const createMetaManager = (config, resolver) => MetaManager.create(config || defaultConfig, resolver || defaultResolver); class MetaManager { constructor(config, target, resolver) { this.ssrCleanedUp = false; @@ -884,7 +885,7 @@ var VueMeta = (function (exports, vue) { }; exports.createMetaManager = createMetaManager; - exports.deepestResolver = deepest; + exports.deepestResolver = defaultResolver; exports.defaultConfig = defaultConfig; exports.getCurrentManager = getCurrentManager; exports.resolveOption = resolveOption; diff --git a/dist/vue-meta.global.min.js b/dist/vue-meta.global.min.js index 7ebdf726..bd79769d 100644 --- a/dist/vue-meta.global.min.js +++ b/dist/vue-meta.global.min.js @@ -1,8 +1,8 @@ /** - * vue-meta v3.0.0-alpha.2 + * vue-meta v3.0.0-alpha.3 * (c) 2021 * - Pim (@pimlie) * - All the amazing contributors * @license MIT */ -var VueMeta=function(t,e){"use strict";const r=t=>(e,r)=>{let o=-1;if(r.reduce(((e,r,n)=>{const s=t(e,r);return s!==e?(o=n,s):e}),void 0),o>-1)return e[o]};const o=r(((t,e)=>{const{depth:r}=e;if(!t||r>t)return t}));var n=Object.freeze({__proto__:null,setup:function(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:o});const s={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}};"production"===process.env.NODE_ENV||Object.freeze({}),"production"===process.env.NODE_ENV||Object.freeze([]);const i=Array.isArray,c=t=>"function"==typeof t,a=t=>"string"==typeof t,u=t=>null!==t&&"object"==typeof t,l=Object.prototype.toString,f=t=>"[object Object]"===l.call(t),d=Symbol("kIsProxy"),p=Symbol("kProxySources"),m=Symbol("kProxyTarget"),b=Symbol("kResolveContext");function h(t){if(i(t))return t.map(h);if(u(t)){const e={};for(const r in t)e[r]="context"===r?t[r]:h(t[r]);return e}return t}const g=(t,e,r)=>{const o=[];for(const n of t)e in n&&(o.push(n[e]),r&&r(n));return o},y=(t,e,r,o=[])=>{if(o.length||(r||(r=t.active),e||(e=t.sources)),!r||!e)return;const n=((t,...e)=>{const r=t?Object.keys(t):[];if(e)for(const t of e)if(t&&u(t))for(const e in t)r.includes(e)||r.push(e);return r})(...e),s=Object.keys(r);for(const t of s)n.includes(t)||delete r[t];for(const s of n){if(f(e[0][s])){r[s]||(r[s]={});const n=[];for(const t of e)s in t&&n.push(t[s]);y(t,n,r[s],[...o,s]);continue}!r[s]&&i(e[0][s])&&(r[s]=[]);const n=[],c=g(e,s,(t=>n.push(t[b])));let a=t.resolve(c,n,r[s],s,o);f(a)&&(a=h(a)),r[s]=a}},v=(t,r,o,n=[])=>{const s=A(t,o,n),i=e.markRaw(new Proxy(r,s));return!n.length&&t.sources&&t.sources.push(i),i},A=(t,e,r=[])=>({get:(o,n,s)=>{if(n===d)return!0;if(n===p)return t.sources;if(n===m)return o;if(n===b)return e;let i=Reflect.get(o,n,s);if(!u(i))return i;if(!i[d]){const s=[...r,n];i=v(t,i,e,s),o[n]=i}return i},set:(e,o,n)=>{const s=Reflect.set(e,o,n);if(s){const n=i(e);let c,a=!1,{sources:u,active:l}=t,d=0;for(const t of r){if(u=g(u,t),n&&d===r.length-1){c=t;break}i(l)&&(a=!0),l=l[t],d++}if(a)return y(t),s;let p,m=[];n?(p=u,m=u.map((t=>t[b]))):p=g(u,o,(t=>m.push(t[b])));let v=t.resolve(p,m,l,o,r);f(v)&&(v=h(v)),n&&c?l[c]=v:l[o]=v}return s},deleteProperty:(e,o)=>{const n=Reflect.deleteProperty(e,o);if(n){const n=i(e);let s,c=t.sources,a=t.active,u=0;for(const t of r){if(c=c.map((e=>e[t])),n&&u===r.length-1){s=t;break}a=a[t],u++}if(c.some((t=>o in t))){let e,i=[];n?(e=c,i=c.map((t=>t[b]))):e=g(c,o,(t=>i.push(t[b])));let u=t.resolve(e,i,a,o,r);f(u)&&(u=h(u)),n&&s?a[s]=u:a[o]=u}else delete a[o]}return n}}),S={};function N(t,e,r,o){return"attributesFor"in o?function(t,e,r,o){const{attributesFor:n}=o;if(!n)return;if(!S[n]){const[t,e]=Array.from(document.querySelectorAll(n));if(!t)return void console.error("Could not find element for selector",n,", won't render attributes");e&&console.warn("Found multiple elements for selector",n),S[n]={el:t,attrs:[]}}const{el:s,attrs:i}=S[n];for(const o in r){const n=w(t,`${e}(${o})`,r[o],r);s.setAttribute(o,n||""),i.includes(o)||i.push(o)}const c=i.filter((t=>!r[t]));for(const t of c)s.removeAttribute(t)}(t,e,r,o):"group"in o?function(t,e,r,o){if(i(r))return console.warn("Specifying an array for group properties isnt supported"),[];return Object.keys(r).map((n=>{const s={group:e,data:r};if(o.namespaced)s.tagNamespace=!0===o.namespaced?e:o.namespaced;else if(o.namespacedAttribute){const t=!0===o.namespacedAttribute?e:o.namespacedAttribute;s.fullName=`${t}:${n}`,s.slotName=`${t}(${n})`}return k(t,e,r[n],o,s)})).flat()}(t,e,r,o):k(t,e,r,o)}function k(t,r,o,n={},c){const u=["content","json","rawContent"],l=t=>function(t,e){for(const r of t){const t=s[r];if(r&&t)return t[e]}}([f,n.tag],t);if(i(o))return o.map((e=>k(t,r,e,n,c))).flat();const{tag:f=n.tag||r}=o;let d="",p=!1,m=!1;if(a(o))d=o;else if(o.children&&i(o.children))p=!0,d=o.children.map((e=>{const o=k(t,r,e,n,c);return i(o)?o.map((({vnode:t})=>t)):o.vnode}));else{let t=0;for(const e of u){if(!d&&o[e]){d=1===t?JSON.stringify(o[e]):o[e],m=t>1;break}t++}}const b=c&&c.fullName||r,h=c&&c.slotName||r;let{attrs:g}=o;if(g||"object"!=typeof o)g||(g={});else{g={...o},delete g.tag,delete g.children,delete g.to;for(const t of u)delete g[t]}if(p)d=w(t,h,d,o);else{const e=!!l("contentAsAttribute");let{valueAttribute:r}=n;if(!r&&e){const[t]=l("attributes");r=a(e)?e:t}if(r){const{nameless:e,keyAttribute:o}=n;e||o&&(g[o]=b),g[r]=w(t,h,g[r]||d,c),d=""}else d=w(t,h,d,o)}const y=c&&c.tagNamespace?`${c.tagNamespace}:${f}`:f;m&&d&&(g.innerHTML=d);const v=e.h(y,g,d||void 0);return{to:o.to,vnode:v}}function w({metainfo:t,slots:e},r,o,n){const s=e&&e[r];if(!s||!c(s))return o;const i={content:o,metainfo:t};if(n&&n.group){const{group:t,data:e}=n;i[t]=e}const a=s(i);if(a&&a.length){const{children:t}=a[0];return t?t.toString():""}return o}const C="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,M=(t=>C?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function O(t){if(t||(t=e.getCurrentInstance()||void 0),t)return t.appContext.config.globalProperties.$metaManager}const j=e.defineComponent({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=O();if(t)return t.render({slots:e})}}),P=e.reactive({});function x(t,r,o){const n=i(o)?o:[o];n.forEach(((t,r)=>{t.type===e.Comment&&n.splice(r,1)})),t[r]||(t[r]=[]),t[r].push(...n)}class ${constructor(t,e,r){this.ssrCleanedUp=!1,this.config=t,this.target=e,r&&"setup"in r&&c(r.setup)&&(this.resolver=r)}install(t){t.component("Metainfo",j),t.config.globalProperties.$metaManager=this,t.provide(M,P)}addMeta(t,r){r||(r=e.getCurrentInstance()||void 0);const o={removed:[]},n={vm:r};this.resolver&&this.resolver.setup(n);const s=this.target.addSource(t,n,!0),i=t=>this.unmount(!!t,s,o,r);return r&&e.onUnmounted(i),{meta:s,onRemoved:t=>o.removed.push(t),unmount:i}}unmount(t,e,r,o){if(o){const{$el:n}=o.proxy;if(n&&n.offsetParent){let o=new MutationObserver((s=>{for(const{removedNodes:i}of s)i&&i.forEach((s=>{s===n&&o&&(o.disconnect(),o=void 0,this.reallyUnmount(t,e,r))}))}));return void o.observe(n.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}={}){this.ssrCleanedUp||(this.ssrCleanedUp=!0,window.addEventListener("DOMContentLoaded",(()=>{const t=document.querySelectorAll("[data-vm-ssr]");t&&t.length&&Array.from(t).forEach((t=>t.parentNode&&t.parentNode.removeChild(t)))})));const r={};for(const e in P){const o=this.config[e]||{};let n=N({metainfo:P,slots:t},e,P[e],o);if(!n)continue;i(n)||(n=[n]);let s="base"!==e&&P[e].to;!s&&"to"in o&&(s=o.to),!s&&"attributesFor"in o&&(s=e);for(const{to:t,vnode:e}of n)x(r,t||s||"head",e)}if(t)for(const e in t){const o="default"===e?"head":e;if("head"!==o&&"body"!==o)continue;const n=t[e];c(n)&&x(r,o,n({metainfo:P}))}return Object.keys(r).map((t=>e.h(e.Teleport,{to:t},r[t])))}}return $.create=(t,e)=>{const r=((t,e={})=>{const r=[];e||(e={});const o={active:e,resolve:t,sources:r},n=()=>y(o);return{context:o,compute:n,addSource:(t,e,r=!1)=>{const s=v(o,t,e||{});return r&&n(),s},delSource:(t,e=!0)=>{const o=r.findIndex((e=>e===t||e[m]===t));return o>-1&&(r.splice(o,1),e&&n(),!0)}}})(((t,r,o,n,s)=>c(e)?e(t,r,o,n,s):e.resolve(t,r,o,n,s)),P);return new $(t,r,e)},t.createMetaManager=(t,e)=>$.create(t,e),t.deepestResolver=n,t.defaultConfig={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"}},t.getCurrentManager=O,t.resolveOption=r,t.useActiveMeta=function(){return e.inject(M)},t.useMeta=function(t,r){const o=e.getCurrentInstance()||void 0;if(!r&&o&&(r=O(o)),!r)throw new Error("No manager or current instance");e.isProxy(t)&&(e.watch(t,((t,e)=>{!function(t,e,r){for(const o in e)o in r?u(t[o])||e[o]!==r[o]&&(t[o]=e[o]):t[o]=e[o];for(const o in r)o in e||delete t[o]}(n.meta,t,e)})),t=t.value);const n=r.addMeta(t,o);return n},Object.defineProperty(t,"__esModule",{value:!0}),t}({},Vue); +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]};const n=r(((t,e)=>{const{depth:r}=e;return!t||r>t?r:t}));var o=Object.freeze({__proto__:null,setup:function(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"),b=Symbol("kProxyTarget"),h=Symbol("kResolveContext");function g(t){if(c(t))return t.map(g);if(l(t)){const e={};for(const r in t)e[r]="context"===r?t[r]:g(t[r]);return e}return t}const y=(t,e,r)=>{const n=[];for(const o of t)e in o&&(n.push(o[e]),r&&r(o));return n},v=(t,e,r,n=[])=>{if(n.length||(r||(r=t.active),e||(e=t.sources)),!r||!e)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})(...e),s=Object.keys(r);for(const t of s)o.includes(t)||delete r[t];for(const s of o){if(d(e[0][s])){r[s]||(r[s]={});const o=[];for(const t of e)s in t&&o.push(t[s]);v(t,o,r[s],[...n,s]);continue}!r[s]&&c(e[0][s])&&(r[s]=[]);const o=[],i=y(e,s,(t=>o.push(t[h])));let a=t.resolve(i,o,r[s],s,n);d(a)&&(a=g(a)),r[s]=a}},A=(t,r,n,o=[])=>{const s=S(t,n,o),i=e.markRaw(new Proxy(r,s));return!o.length&&t.sources&&t.sources.push(i),i},S=(t,e,r=[])=>({get:(n,o,s)=>{if(o===p)return!0;if(o===m)return t.sources;if(o===b)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=A(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 o=c(e);let i,a=!1,{sources:u,active:l}=t,f=0;for(const t of r){if(u=y(u,t),o&&f===r.length-1){i=t;break}c(l)&&(a=!0),l=l[t],f++}if(a)return v(t),s;let p,m=[];o?(p=u,m=u.map((t=>t[h]))):p=y(u,n,(t=>m.push(t[h])));let b=t.resolve(p,m,l,n,r);d(b)&&(b=g(b)),o&&i?l[i]=b:l[n]=b}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[t])),o&&u===r.length-1){s=t;break}a=a[t],u++}if(i.some((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=g(u)),o&&s?a[s]=u:a[n]=u}else delete a[n]}return o}}),k={};function w(t,e,r,n){return"attributesFor"in n?function(t,e,r,n){const{attributesFor:o}=n;if(!o)return;if(!k[o]){const[t,e]=Array.from(document.querySelectorAll(o));if(!t)return void console.error("Could not find element for selector",o,", won't render attributes");e&&console.warn("Found multiple elements for selector",o),k[o]={el:t,attrs:[]}}const{el:s,attrs:i}=k[o];for(const n in r){const o=M(t,`${e}(${n})`,r[n],r);s.setAttribute(n,o||""),i.includes(n)||i.push(n)}const c=i.filter((t=>!r[t]));for(const t of c)s.removeAttribute(t)}(t,e,r,n):"group"in n?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)})).flat()}(t,e,r,n):C(t,e,r,n)}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))).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.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 b=s&&s.fullName||r,h=s&&s.slotName||r;let{attrs:g}=n;if(g||"object"!=typeof n)g||(g={});else{g={...n},delete g.tag,delete g.children,delete g.to;for(const t of a)delete g[t]}if(p)d=M(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,keyAttribute:n}=o;e||n&&(g[n]=b),g[r]=M(t,h,g[r]||d,s),d=""}else d=M(t,h,d,n)}const y=s&&s.tagNamespace?`${s.tagNamespace}:${f}`:f;m&&d&&(g.innerHTML=d);const v=e.h(y,g,d||void 0);return{to:n.to,vnode:v}}function M({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 j="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,O=(t=>j?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function N(t){if(t||(t=e.getCurrentInstance()||void 0),t)return t.appContext.config.globalProperties.$metaManager}const P=e.defineComponent({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=N();if(t)return t.render({slots:e})}}),x=e.reactive({});function $(t,r,n){const o=c(n)?n:[n];o.forEach(((t,r)=>{t.type===e.Comment&&o.splice(r,1)})),t[r]||(t[r]=[]),t[r].push(...o)}class R{constructor(t,e,r){this.ssrCleanedUp=!1,this.config=t,this.target=e,r&&"setup"in r&&a(r.setup)&&(this.resolver=r)}install(t){t.component("Metainfo",P),t.config.globalProperties.$metaManager=this,t.provide(O,x)}addMeta(t,r){r||(r=e.getCurrentInstance()||void 0);const n={removed:[]},o={vm:r};this.resolver&&this.resolver.setup(o);const s=this.target.addSource(t,o,!0),i=t=>this.unmount(!!t,s,n,r);return r&&e.onUnmounted(i),{meta:s,onRemoved:t=>n.removed.push(t),unmount:i}}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}={}){this.ssrCleanedUp||(this.ssrCleanedUp=!0,window.addEventListener("DOMContentLoaded",(()=>{const t=document.querySelectorAll("[data-vm-ssr]");t&&t.length&&Array.from(t).forEach((t=>t.parentNode&&t.parentNode.removeChild(t)))})));const r={};for(const e in x){const n=this.config[e]||{};let o=w({metainfo:x,slots:t},e,x[e],n);if(!o)continue;c(o)||(o=[o]);let s="base"!==e&&x[e].to;!s&&"to"in n&&(s=n.to),!s&&"attributesFor"in n&&(s=e);for(const{to:t,vnode:e}of o)$(r,t||s||"head",e)}if(t)for(const e in t){const n="default"===e?"head":e;if("head"!==n&&"body"!==n)continue;const o=t[e];a(o)&&$(r,n,o({metainfo:x}))}return Object.keys(r).map((t=>e.h(e.Teleport,{to:t},r[t])))}}return R.create=(t,e)=>{const r=((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=A(n,t,e||{});return r&&o(),s},delSource:(t,e=!0)=>{const n=r.findIndex((e=>e===t||e[b]===t));return n>-1&&(r.splice(n,1),e&&o(),!0)}}})(((t,r,n,o,s)=>a(e)?e(t,r,n,o,s):e.resolve(t,r,n,o,s)),x);return new R(t,r,e)},t.createMetaManager=(t,e)=>R.create(t||s,e||o),t.deepestResolver=o,t.defaultConfig=s,t.getCurrentManager=N,t.resolveOption=r,t.useActiveMeta=function(){return e.inject(O)},t.useMeta=function(t,r){const n=e.getCurrentInstance()||void 0;if(!r&&n&&(r=N(n)),!r)throw new Error("No manager or current instance");e.isProxy(t)&&(e.watch(t,((t,e)=>{!function(t,e,r){for(const n in e)n in r?l(t[n])||e[n]!==r[n]&&(t[n]=e[n]):t[n]=e[n];for(const n in r)n in e||delete t[n]}(o.meta,t,e)})),t=t.value);const o=r.addMeta(t,n);return o},Object.defineProperty(t,"__esModule",{value:!0}),t}({},Vue); diff --git a/package.json b/package.json index b462cf70..93e744ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-meta", - "version": "3.0.0-alpha.2", + "version": "3.0.0-alpha.3", "description": "Manage HTML metadata in Vue.js components with SSR support", "main": "dist/vue-meta.cjs.js", "unpkg": "dist/vue-meta.global.js",