@vueuse/head
Advanced tools
Comparing version 1.0.0-rc.3 to 1.0.0-rc.4
@@ -34,2 +34,4 @@ import * as vue from 'vue'; | ||
* @deprecated This can only be used with `useHeadRaw`. | ||
* | ||
* Alias for children | ||
*/ | ||
@@ -39,4 +41,2 @@ innerHTML?: string; | ||
* Sets the textContent of an element. | ||
* | ||
* @deprecated Use `textContent` instead. | ||
*/ | ||
@@ -46,2 +46,4 @@ children?: string; | ||
* Sets the textContent of an element. This will be HTML encoded. | ||
* | ||
* Alias for children | ||
*/ | ||
@@ -98,14 +100,15 @@ textContent?: string; | ||
} | ||
declare type HookBeforeDomUpdate = ((tags: HeadTag[]) => Promise<void | boolean> | void | boolean)[]; | ||
declare type HookTagsResolved = ((tags: HeadTag[]) => Promise<void> | void)[]; | ||
declare type HeadTagRuntime = HeadEntryOptions & HandlesDuplicates & HasRenderPriority & RendersToBody & HasTextContent & { | ||
position: number; | ||
entryId: number; | ||
}; | ||
declare type HookBeforeDomUpdate = (() => Promise<void | boolean> | void | boolean); | ||
declare type HookTagsResolved = ((tags: HeadTag[]) => Promise<void> | void); | ||
declare type HookEntriesResolved = ((entries: HeadEntry[]) => Promise<void> | void); | ||
declare type HeadTagOptions = HeadEntryOptions & HandlesDuplicates & HasRenderPriority & RendersToBody & HasTextContent; | ||
interface HeadTag { | ||
tag: TagKeys; | ||
props: { | ||
[k: string]: any; | ||
props: Record<string, any>; | ||
children?: string; | ||
runtime?: { | ||
position?: number; | ||
entryId?: number; | ||
}; | ||
_runtime: HeadTagRuntime; | ||
options?: HeadTagOptions; | ||
} | ||
@@ -153,3 +156,3 @@ interface HeadObjectApi<T extends MergeHead = {}> { | ||
declare const tagToString: (tag: HeadTag) => string; | ||
declare const resolveHeadEntry: (entries: HeadEntry[], force?: boolean) => HeadEntry<{}>[]; | ||
declare const resolveHeadEntries: (entries: HeadEntry[], force?: boolean) => HeadEntry<{}>[]; | ||
declare const renderHeadToString: <T extends MergeHead = {}>(head: HeadClient<T>) => Promise<HTMLResult>; | ||
@@ -166,5 +169,14 @@ | ||
headEntries: HeadEntry<T>[]; | ||
/** | ||
* Backwards compatibility function to fetch the headTags. | ||
* | ||
* This function forces reactivity resolving and is not performant. | ||
* | ||
* @deprecated Use hooks. | ||
*/ | ||
headTags: HeadTag[]; | ||
addEntry: (entry: UseHeadInput<T>, options?: HeadEntryOptions) => HeadObjectApi<T>; | ||
addReactiveEntry: (objs: UseHeadInput<T>, options?: HeadEntryOptions) => () => void; | ||
updateDOM: (document?: Document, force?: boolean) => void; | ||
hooks: | ||
/** | ||
@@ -178,7 +190,7 @@ * Array of user provided functions to hook into before the DOM is updated. | ||
*/ | ||
hookBeforeDomUpdate: HookBeforeDomUpdate; | ||
Record<'before:dom', HookBeforeDomUpdate[]> & Record<'resolved:entries', HookEntriesResolved[]> & | ||
/** | ||
* Array of user provided functions to hook into after the tags have been resolved (deduped and sorted). | ||
*/ | ||
hookTagsResolved: HookTagsResolved; | ||
* Array of user provided functions to hook into after the tags have been resolved (deduped and sorted). | ||
*/ | ||
Record<'resolved:tags', HookTagsResolved[]>; | ||
} | ||
@@ -195,2 +207,2 @@ declare const IS_BROWSER: boolean; | ||
export { HTMLResult, HandlesDuplicates, HasRenderPriority, HasTextContent, Head, HeadAttrs, HeadClient, HeadEntry, HeadEntryOptions, HeadObject, HeadObjectApi, HeadObjectPlain, HeadTag, HeadTagRuntime, HookBeforeDomUpdate, HookTagsResolved, IS_BROWSER, Never, RendersToBody, ResolvedUseHeadInput, TagKeys, UseHeadInput, UseHeadRawInput, VueUseHeadSchema, createElement, createHead, escapeHtml, escapeJS, headInputToTags, injectHead, isEqualNode, renderHeadToString, resolveHeadEntriesToTags, resolveHeadEntry, resolveUnrefHeadInput, setAttrs, sortTags, stringifyAttrName, stringifyAttrValue, stringifyAttrs, tagDedupeKey, tagToString, updateElements, useHead, useHeadRaw }; | ||
export { HTMLResult, HandlesDuplicates, HasRenderPriority, HasTextContent, Head, HeadAttrs, HeadClient, HeadEntry, HeadEntryOptions, HeadObject, HeadObjectApi, HeadObjectPlain, HeadTag, HeadTagOptions, HookBeforeDomUpdate, HookEntriesResolved, HookTagsResolved, IS_BROWSER, Never, RendersToBody, ResolvedUseHeadInput, TagKeys, UseHeadInput, UseHeadRawInput, VueUseHeadSchema, createElement, createHead, escapeHtml, escapeJS, headInputToTags, injectHead, isEqualNode, renderHeadToString, resolveHeadEntries, resolveHeadEntriesToTags, resolveUnrefHeadInput, setAttrs, sortTags, stringifyAttrName, stringifyAttrValue, stringifyAttrs, tagDedupeKey, tagToString, updateElements, useHead, useHeadRaw }; |
@@ -33,4 +33,4 @@ "use strict"; | ||
renderHeadToString: () => renderHeadToString, | ||
resolveHeadEntries: () => resolveHeadEntries, | ||
resolveHeadEntriesToTags: () => resolveHeadEntriesToTags, | ||
resolveHeadEntry: () => resolveHeadEntry, | ||
resolveUnrefHeadInput: () => resolveUnrefHeadInput, | ||
@@ -109,17 +109,12 @@ setAttrs: () => setAttrs, | ||
var tagToString = (tag) => { | ||
var _a; | ||
const body = tag._runtime.body ? ` ${BODY_TAG_ATTR_NAME}="true"` : ""; | ||
const attrs = stringifyAttrs(tag.props, tag._runtime); | ||
var _a, _b; | ||
const body = ((_a = tag.options) == null ? void 0 : _a.body) ? ` ${BODY_TAG_ATTR_NAME}="true"` : ""; | ||
const attrs = stringifyAttrs(tag.props, tag.options); | ||
if (SELF_CLOSING_TAGS.includes(tag.tag)) | ||
return `<${tag.tag}${attrs}${body}>`; | ||
let innerContent = ""; | ||
if (((_a = tag._runtime) == null ? void 0 : _a.raw) && tag._runtime.innerHTML) | ||
innerContent = tag._runtime.innerHTML; | ||
if (!innerContent && tag._runtime.textContent) | ||
innerContent = escapeJS(escapeHtml(tag._runtime.textContent)); | ||
if (!innerContent && tag._runtime.children) | ||
innerContent = escapeJS(escapeHtml(tag._runtime.children)); | ||
return `<${tag.tag}${attrs}${body}>${innerContent}</${tag.tag}>`; | ||
let children = tag.children || ""; | ||
children = ((_b = tag.options) == null ? void 0 : _b.raw) ? children : escapeJS(escapeHtml(children)); | ||
return `<${tag.tag}${attrs}${body}>${children}</${tag.tag}>`; | ||
}; | ||
var resolveHeadEntry = (entries, force) => { | ||
var resolveHeadEntries = (entries, force) => { | ||
return entries.map((e) => { | ||
@@ -132,2 +127,3 @@ if (e.input && (force || !e.resolved)) | ||
var renderHeadToString = async (head) => { | ||
var _a; | ||
const headHtml = []; | ||
@@ -137,6 +133,8 @@ const bodyHtml = []; | ||
const attrs = { htmlAttrs: {}, bodyAttrs: {} }; | ||
const resolvedEntries = resolveHeadEntry(head.headEntries, true); | ||
const resolvedEntries = resolveHeadEntries(head.headEntries); | ||
for (const h in head.hooks["resolved:entries"]) | ||
await head.hooks["resolved:entries"][h](resolvedEntries); | ||
const headTags = resolveHeadEntriesToTags(resolvedEntries); | ||
for (const h in head.hookTagsResolved) | ||
await head.hookTagsResolved[h](headTags); | ||
for (const h in head.hooks["resolved:tags"]) | ||
await head.hooks["resolved:tags"][h](headTags); | ||
for (const tag of headTags) { | ||
@@ -149,3 +147,3 @@ if (tag.tag === "title") { | ||
} | ||
} else if (tag._runtime.body) { | ||
} else if ((_a = tag.options) == null ? void 0 : _a.body) { | ||
bodyHtml.push(tagToString(tag)); | ||
@@ -188,4 +186,5 @@ } else { | ||
const tagWeight = (tag) => { | ||
if (tag._runtime.renderPriority) | ||
return tag._runtime.renderPriority; | ||
var _a; | ||
if ((_a = tag.options) == null ? void 0 : _a.renderPriority) | ||
return tag.options.renderPriority; | ||
switch (tag.tag) { | ||
@@ -207,3 +206,3 @@ case "base": | ||
var tagDedupeKey = (tag) => { | ||
const { props, tag: tagName, _runtime } = tag; | ||
const { props, tag: tagName, options } = tag; | ||
if (tagName === "base" || tagName === "title") | ||
@@ -215,4 +214,4 @@ return tagName; | ||
return "charset"; | ||
if (_runtime.key) | ||
return `${tagName}:${_runtime.key}`; | ||
if (options == null ? void 0 : options.key) | ||
return `${tagName}:${options.key}`; | ||
const name = ["id"]; | ||
@@ -226,3 +225,3 @@ if (tagName === "meta") | ||
} | ||
return tag._runtime.position; | ||
return tag.runtime.position; | ||
}; | ||
@@ -254,24 +253,29 @@ function resolveUnrefHeadInput(ref2) { | ||
tag: name, | ||
props: [], | ||
_runtime: { | ||
props: {}, | ||
runtime: { | ||
entryId: e.id, | ||
position: 0 | ||
}, | ||
options: { | ||
...e.options | ||
} | ||
}; | ||
["hid", "vmid"].forEach((key) => { | ||
["hid", "vmid", "key"].forEach((key) => { | ||
if (input[key]) { | ||
tag._runtime.key = input[key]; | ||
tag.options.key = input[key]; | ||
delete input[key]; | ||
} | ||
}); | ||
tag._runtime = { | ||
...tag._runtime, | ||
...e.options | ||
}; | ||
["body", "renderPriority", "key", "children", "innerHTML", "textContent"].forEach((key) => { | ||
["children", "innerHTML", "textContent"].forEach((key) => { | ||
if (typeof input[key] !== "undefined") { | ||
tag._runtime[key] = input[key]; | ||
tag.children = input[key]; | ||
delete input[key]; | ||
} | ||
}); | ||
["body", "renderPriority"].forEach((key) => { | ||
if (typeof input[key] !== "undefined") { | ||
tag.options[key] = input[key]; | ||
delete input[key]; | ||
} | ||
}); | ||
tag.props = input; | ||
@@ -285,3 +289,3 @@ return tag; | ||
case "title": | ||
return resolveTag(key, { textContent: props }, e); | ||
return resolveTag(key, { children: props }, e); | ||
case "base": | ||
@@ -311,3 +315,3 @@ case "meta": | ||
const deduping = {}; | ||
const resolvedEntries = resolveHeadEntry(entries); | ||
const resolvedEntries = resolveHeadEntries(entries); | ||
const titleTemplate = resolvedEntries.map((i) => i.input.titleTemplate).reverse().find((i) => i != null); | ||
@@ -318,10 +322,11 @@ resolvedEntries.forEach((entry, entryIndex) => { | ||
var _a; | ||
tag._runtime.position = entryIndex * 1e4 + tagIdx; | ||
tag.runtime = tag.runtime || {}; | ||
tag.runtime.position = entryIndex * 1e4 + tagIdx; | ||
if (titleTemplate && tag.tag === "title") { | ||
tag._runtime.textContent = renderTitleTemplate( | ||
tag.children = renderTitleTemplate( | ||
titleTemplate, | ||
tag._runtime.textContent | ||
tag.children | ||
); | ||
} | ||
if (!((_a = tag._runtime) == null ? void 0 : _a.raw)) { | ||
if (!((_a = tag.options) == null ? void 0 : _a.raw)) { | ||
for (const k in tag.props) { | ||
@@ -335,3 +340,3 @@ if (k.startsWith("on") || k === "innerHTML") | ||
}); | ||
return Object.values(deduping).sort((a, b) => a._runtime.position - b._runtime.position).sort(sortTags); | ||
return Object.values(deduping).sort((a, b) => a.runtime.position - b.runtime.position).sort(sortTags); | ||
}; | ||
@@ -379,2 +384,3 @@ | ||
var createElement = (tag, document) => { | ||
var _a, _b; | ||
const $el = document.createElement(tag.tag); | ||
@@ -385,9 +391,7 @@ Object.entries(tag.props).forEach(([k, v]) => { | ||
}); | ||
if (tag._runtime.body === true) { | ||
if ((_a = tag.options) == null ? void 0 : _a.body) { | ||
$el.setAttribute(BODY_TAG_ATTR_NAME, "true"); | ||
} | ||
if (tag._runtime.raw && tag._runtime.innerHTML) | ||
$el.innerHTML = tag._runtime.innerHTML; | ||
else | ||
$el.textContent = tag._runtime.textContent || tag._runtime.children || ""; | ||
if (tag.children) | ||
$el[((_b = tag.options) == null ? void 0 : _b.raw) ? "innerHTML" : "textContent"] = tag.children; | ||
return $el; | ||
@@ -423,6 +427,9 @@ }; | ||
} | ||
let newElements = tags.map((tag) => ({ | ||
element: createElement(tag, document), | ||
body: tag._runtime.body ?? false | ||
})); | ||
let newElements = tags.map((tag) => { | ||
var _a2; | ||
return { | ||
element: createElement(tag, document), | ||
body: ((_a2 = tag.options) == null ? void 0 : _a2.body) ?? false | ||
}; | ||
}); | ||
newElements = newElements.filter((newEl) => { | ||
@@ -471,14 +478,17 @@ for (let i = 0; i < oldHeadElements.length; i++) { | ||
document = window.document; | ||
const headTags = resolveHeadEntriesToTags(head.headEntries); | ||
for (const h in head.hookTagsResolved) | ||
await head.hookTagsResolved[h](headTags); | ||
for (const k in head.hookBeforeDomUpdate) { | ||
if (await head.hookBeforeDomUpdate[k](headTags) === false) | ||
for (const k in head.hooks["before:dom"]) { | ||
if (await head.hooks["before:dom"][k]() === false) | ||
return; | ||
} | ||
const resolvedEntries = resolveHeadEntries(head.headEntries); | ||
for (const h in head.hooks["resolved:entries"]) | ||
await head.hooks["resolved:entries"][h](resolvedEntries); | ||
const headTags = resolveHeadEntriesToTags(resolvedEntries); | ||
for (const h in head.hooks["resolved:tags"]) | ||
await head.hooks["resolved:tags"][h](headTags); | ||
for (const tag of headTags) { | ||
switch (tag.tag) { | ||
case "title": | ||
if (typeof tag._runtime.textContent !== "undefined") | ||
document.title = tag._runtime.textContent; | ||
if (typeof tag.children !== "undefined") | ||
document.title = tag.children; | ||
break; | ||
@@ -513,4 +523,3 @@ case "base": | ||
if (node.children) { | ||
const k = type === "script" ? "innerHTML" : "textContent"; | ||
props[k] = Array.isArray(node.children) ? node.children[0].children : node.children; | ||
props.children = Array.isArray(node.children) ? node.children[0].children : node.children; | ||
} | ||
@@ -520,3 +529,3 @@ if (Array.isArray(obj[type])) | ||
else if (type === "title") | ||
obj.title = props.textContent; | ||
obj.title = props.children; | ||
else | ||
@@ -583,4 +592,2 @@ obj[type] = props; | ||
const previousTags = /* @__PURE__ */ new Set(); | ||
const hookBeforeDomUpdate = []; | ||
const hookTagsResolved = []; | ||
let domUpdateTick = null; | ||
@@ -592,7 +599,14 @@ const head = { | ||
}, | ||
hookBeforeDomUpdate, | ||
hookTagsResolved, | ||
hooks: { | ||
"before:dom": [], | ||
"resolved:tags": [], | ||
"resolved:entries": [] | ||
}, | ||
get headEntries() { | ||
return entries; | ||
}, | ||
get headTags() { | ||
const resolvedEntries = resolveHeadEntries(head.headEntries); | ||
return resolveHeadEntriesToTags(resolvedEntries); | ||
}, | ||
addEntry(input, options = {}) { | ||
@@ -689,4 +703,4 @@ let resolved = false; | ||
renderHeadToString, | ||
resolveHeadEntries, | ||
resolveHeadEntriesToTags, | ||
resolveHeadEntry, | ||
resolveUnrefHeadInput, | ||
@@ -693,0 +707,0 @@ setAttrs, |
{ | ||
"name": "@vueuse/head", | ||
"version": "1.0.0-rc.3", | ||
"version": "1.0.0-rc.4", | ||
"packageManager": "pnpm@7.5.0", | ||
@@ -5,0 +5,0 @@ "description": "Document head manager for Vue 3. SSR ready.", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
59860
1514