mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-20 18:40:33 +03:00
9 lines
9.3 KiB
JavaScript
9 lines
9.3 KiB
JavaScript
/**
|
|
* vue-meta v3.0.0-alpha.7
|
|
* (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,onUnmounted as c,Teleport as a,reactive 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]},d=f(((t,e)=>{const{depth:o}=e;return!t||o>t?o:t}));var p=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: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"}},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 b=Array.isArray,g=t=>"function"==typeof t,y=t=>"string"==typeof t,v=t=>null!==t&&"object"==typeof t,S=Object.prototype.toString,A=t=>"[object Object]"===S.call(t),k=Symbol("kIsProxy"),R=Symbol("kProxySources"),j=Symbol("kProxyTarget"),w=Symbol("kResolveContext");function x(t){if(b(t))return t.map(x);if(v(t)){const e={};for(const o in t)e[o]="context"===o?t[o]:x(t[o]);return e}return t}const N=(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;t<e.length;t++){const n=e[t];if(!o||!o[n])return void console.error(`recompute: segment ${n} not found on target`,e,o);o=o[n],r=r.map((t=>t[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&&v(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;t<r.length;t++){const e=r[t];if(e&&s in e&&void 0!==e[s]){n=A(e[s]);break}}if(n){o[s]||(o[s]={});const n=[];for(const t of r)s in t&&n.push(t[s]);$(t,[...e,s],o[s],n);continue}!o[s]&&b(r[0][s])&&(o[s]=[]);const i=[],c=N(r,s,(t=>i.push(t[w])));let a=t.resolve(c,i,o[s],s,e);A(a)&&(a=x(a)),o[s]=a}},O=(e,o,r,n=[])=>{const s=P(e,r,n),i=t(new Proxy(o,s));return!n.length&&e.sources&&e.sources.push(i),i},P=(t,e,o=[])=>({get:(r,n,s)=>{if(n===k)return!0;if(n===R)return t.sources;if(n===j)return r;if(n===w)return e;let i=Reflect.get(r,n,s);if(!v(i))return i;if(!i[k]){const s=[...o,n];i=O(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=b(e);let c,a=!1,{sources:u,active:l}=t,f=0;for(const t of o){if(u=N(u,t),i&&f===o.length-1){c=t;break}b(l)&&(a=!0),l=l[t],f++}if(a)return $(t),s;if(A(n))return $(t,o),s;let d,p=[];i?(d=u,p=u.map((t=>t[w]))):d=N(u,r,(t=>p.push(t[w])));let m=t.resolve(d,p,l,r,o);A(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=b(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=N(i,r,(t=>a.push(t[w])));let u=t.resolve(e,a,c,r,o);A(u)&&(u=x(u)),n&&s?c[s]=u:c[r]=u}else delete c[r]}return n}}),C={};function M(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(!C[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),C[s]={el:t,attrs:[]}}const{el:i,attrs:c}=C[s];for(const e in r){let n=E(t,`${o}(${e})`,r[e],r);b(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(b(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)})).filter(Boolean).flat()}(t,o,r,n):F(t,o,r,n)}function F(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(b(r))return r.map((e=>F(t,o,e,n,s))).filter(Boolean).flat();const{tag:a=n.tag||o}=r;let u="",l=!1,f=!1;if(y(r))u=r;else if(r.children&&b(r.children))l=!0,u=r.children.map((e=>{const r=F(t,o,e,n,s);return b(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=E(t,p,u,r);else{const e=!!c("contentAsAttribute");let{valueAttribute:o}=n;if(!o&&e){const[t]=c("attributes");o=y(e)?e:t}if(o){const{nameless:e}=n;if(!e){const t=n.keyAttribute||c("keyAttribute");t&&(m[t]=d)}m[o]=E(t,p,m[o]||u,s),u=""}else u=E(t,p,u,r)}const g=s&&s.tagNamespace?`${s.tagNamespace}:${a}`:a;if("title"===g&&!t.isSSR)return void(document.title=u);f&&u&&(m.innerHTML=u);const v=e(g,m,u||void 0);return{to:r.to,vnode:v}}function E({metainfo:t,slots:e},o,r,n){const s=e&&e[o];if(!s||!g(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 U="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,z=(t=>U?Symbol("[vue-meta]: "+t):"[vue-meta]: "+t)("meta_active");function _(t,e,o){for(const r in e)r in o?v(t[r])?_(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 L(t){if(t||(t=o()||void 0),t)return t.appContext.config.globalProperties.$metaManager}function q(t,e){const s=o()||void 0;if(!e&&s&&(e=L(s)),!e)throw new Error("No manager or current instance");r(t)&&(n(t,((t,e)=>{_(i.meta,t,e)})),t=t.value);const i=e.addMeta(t,s);return i}function B(){return s(z)}const T=i({name:"Metainfo",inheritAttrs:!1,setup:(t,{slots:e})=>()=>{const t=L();if(t)return t.render({slots:e})}});function I(t,e,o,r){const n=b(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 D=(t=!1,e,o)=>H.create(t,e||m,o||p);class H{constructor(t,e,o,r){this.isSSR=!1,this.ssrCleanedUp=!1,this.isSSR=t,this.config=e,this.target=o,r&&"setup"in r&&g(r.setup)&&(this.resolver=r)}install(t){t.component("Metainfo",T),t.config.globalProperties.$metaManager=this,t.provide(z,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),a=t=>this.unmount(!!t,i,r,e);return e&&c(a),{meta:i,onRemoved:t=>r.removed.push(t),unmount:a}}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=M({isSSR:r,metainfo:o,slots:t},e,o[e],s);if(!i)continue;b(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)I(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];g(s)&&I(this.isSSR,n,r,s({metainfo:o}))}return Object.keys(n).map((t=>e(a,{to:t},n[t])))}}H.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=O(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,e,r,n,s)=>g(o)?o(t,e,r,n,s):o.resolve(t,e,r,n,s)),u({}));return new H(t,e,r,o)};export{D as createMetaManager,p as deepestResolver,m as defaultConfig,L as getCurrentManager,f as resolveOption,B as useActiveMeta,q as useMeta};
|