@solidjs/meta
Advanced tools
Comparing version 0.28.6 to 0.28.7
@@ -7,3 +7,23 @@ import { mergeProps as _$mergeProps } from "solid-js/web"; | ||
const cascadingTags = ["title", "meta"]; | ||
const getTagType = tag => tag.tag + (tag.name ? `.${tag.name}"` : ""); | ||
// https://html.spec.whatwg.org/multipage/semantics.html#the-title-element | ||
const titleTagProperties = []; | ||
const metaTagProperties = | ||
// https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element | ||
["name", "http-equiv", "content", "charset", "media"] | ||
// additional properties | ||
.concat(["property"]); | ||
const getTagKey = (tag, properties) => { | ||
// pick allowed properties and sort them | ||
const tagProps = Object.fromEntries(Object.entries(tag.props).filter(([k]) => properties.includes(k)).sort()); | ||
// treat `property` as `name` for meta tags | ||
if (Object.hasOwn(tagProps, "name") || Object.hasOwn(tagProps, "property")) { | ||
tagProps.name = tagProps.name || tagProps.property; | ||
delete tagProps.property; | ||
} | ||
// concat tag name and properties as unique key for this tag | ||
return tag.tag + JSON.stringify(tagProps); | ||
}; | ||
const MetaProvider = props => { | ||
@@ -43,9 +63,11 @@ if (!isServer && !sharedConfig.context) { | ||
addClientTag: tag => { | ||
let tagType = getTagType(tag); | ||
if (cascadingTags.indexOf(tag.tag) !== -1) { | ||
const properties = tag.tag === "title" ? titleTagProperties : metaTagProperties; | ||
const tagKey = getTagKey(tag, properties); | ||
// only cascading tags need to be kept as singletons | ||
if (!cascadedTagInstances.has(tagType)) { | ||
cascadedTagInstances.set(tagType, []); | ||
if (!cascadedTagInstances.has(tagKey)) { | ||
cascadedTagInstances.set(tagKey, []); | ||
} | ||
let instances = cascadedTagInstances.get(tagType); | ||
let instances = cascadedTagInstances.get(tagKey); | ||
let index = instances.length; | ||
@@ -55,3 +77,3 @@ instances = [...instances, tag]; | ||
// track indices synchronously | ||
cascadedTagInstances.set(tagType, instances); | ||
cascadedTagInstances.set(tagKey, instances); | ||
if (!isServer) { | ||
@@ -88,5 +110,6 @@ let element = getElement(tag); | ||
removeClientTag: (tag, index) => { | ||
const tagName = getTagType(tag); | ||
const properties = tag.tag === "title" ? titleTagProperties : metaTagProperties; | ||
const tagKey = getTagKey(tag, properties); | ||
if (tag.ref) { | ||
const t = cascadedTagInstances.get(tagName); | ||
const t = cascadedTagInstances.get(tagKey); | ||
if (t) { | ||
@@ -102,3 +125,3 @@ if (tag.ref.parentNode) { | ||
t[index] = null; | ||
cascadedTagInstances.set(tagName, t); | ||
cascadedTagInstances.set(tagKey, t); | ||
} else { | ||
@@ -119,7 +142,5 @@ if (tag.ref.parentNode) { | ||
if (cascadingTags.indexOf(tagDesc.tag) !== -1) { | ||
const index = tags.findIndex(prev => { | ||
const prevName = prev.props.name || prev.props.property; | ||
const nextName = tagDesc.props.name || tagDesc.props.property; | ||
return prev.tag === tagDesc.tag && prevName === nextName; | ||
}); | ||
const properties = tagDesc.tag === "title" ? titleTagProperties : metaTagProperties; | ||
const tagDescKey = getTagKey(tagDesc, properties); | ||
const index = tags.findIndex(prev => prev.tag === tagDesc.tag && getTagKey(prev, properties) === tagDescKey); | ||
if (index !== -1) { | ||
@@ -126,0 +147,0 @@ tags.splice(index, 1); |
@@ -5,3 +5,22 @@ import { createContext, createRenderEffect, createUniqueId, onCleanup, sharedConfig, useContext } from "solid-js"; | ||
const cascadingTags = ["title", "meta"]; | ||
const getTagType = (tag) => tag.tag + (tag.name ? `.${tag.name}"` : ""); | ||
// https://html.spec.whatwg.org/multipage/semantics.html#the-title-element | ||
const titleTagProperties = []; | ||
const metaTagProperties = | ||
// https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element | ||
["name", "http-equiv", "content", "charset", "media"] | ||
// additional properties | ||
.concat(["property"]); | ||
const getTagKey = (tag, properties) => { | ||
// pick allowed properties and sort them | ||
const tagProps = Object.fromEntries(Object.entries(tag.props) | ||
.filter(([k]) => properties.includes(k)) | ||
.sort()); | ||
// treat `property` as `name` for meta tags | ||
if (Object.hasOwn(tagProps, "name") || Object.hasOwn(tagProps, "property")) { | ||
tagProps.name = tagProps.name || tagProps.property; | ||
delete tagProps.property; | ||
} | ||
// concat tag name and properties as unique key for this tag | ||
return tag.tag + JSON.stringify(tagProps); | ||
}; | ||
const MetaProvider = props => { | ||
@@ -41,13 +60,14 @@ if (!isServer && !sharedConfig.context) { | ||
addClientTag: (tag) => { | ||
let tagType = getTagType(tag); | ||
if (cascadingTags.indexOf(tag.tag) !== -1) { | ||
const properties = tag.tag === "title" ? titleTagProperties : metaTagProperties; | ||
const tagKey = getTagKey(tag, properties); | ||
// only cascading tags need to be kept as singletons | ||
if (!cascadedTagInstances.has(tagType)) { | ||
cascadedTagInstances.set(tagType, []); | ||
if (!cascadedTagInstances.has(tagKey)) { | ||
cascadedTagInstances.set(tagKey, []); | ||
} | ||
let instances = cascadedTagInstances.get(tagType); | ||
let instances = cascadedTagInstances.get(tagKey); | ||
let index = instances.length; | ||
instances = [...instances, tag]; | ||
// track indices synchronously | ||
cascadedTagInstances.set(tagType, instances); | ||
cascadedTagInstances.set(tagKey, instances); | ||
if (!isServer) { | ||
@@ -84,5 +104,6 @@ let element = getElement(tag); | ||
removeClientTag: (tag, index) => { | ||
const tagName = getTagType(tag); | ||
const properties = tag.tag === "title" ? titleTagProperties : metaTagProperties; | ||
const tagKey = getTagKey(tag, properties); | ||
if (tag.ref) { | ||
const t = cascadedTagInstances.get(tagName); | ||
const t = cascadedTagInstances.get(tagKey); | ||
if (t) { | ||
@@ -98,3 +119,3 @@ if (tag.ref.parentNode) { | ||
t[index] = null; | ||
cascadedTagInstances.set(tagName, t); | ||
cascadedTagInstances.set(tagKey, t); | ||
} | ||
@@ -114,7 +135,5 @@ else { | ||
if (cascadingTags.indexOf(tagDesc.tag) !== -1) { | ||
const index = tags.findIndex(prev => { | ||
const prevName = prev.props.name || prev.props.property; | ||
const nextName = tagDesc.props.name || tagDesc.props.property; | ||
return prev.tag === tagDesc.tag && prevName === nextName; | ||
}); | ||
const properties = tagDesc.tag === "title" ? titleTagProperties : metaTagProperties; | ||
const tagDescKey = getTagKey(tagDesc, properties); | ||
const index = tags.findIndex(prev => prev.tag === tagDesc.tag && getTagKey(prev, properties) === tagDescKey); | ||
if (index !== -1) { | ||
@@ -121,0 +140,0 @@ tags.splice(index, 1); |
{ | ||
"name": "@solidjs/meta", | ||
"description": "Write meta tags to the document head", | ||
"version": "0.28.6", | ||
"version": "0.28.7", | ||
"author": "Ryan Carniato", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
20359
443