react-helmet-async
Advanced tools
Comparing version 2.0.0-alpha to 2.0.1-alpha
1521
lib/index.js
"use strict"; | ||
(() => { | ||
var __create = Object.create; | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { | ||
get: (a, b) => (typeof require !== "undefined" ? require : a)[b] | ||
}) : x)(function(x) { | ||
if (typeof require !== "undefined") | ||
return require.apply(this, arguments); | ||
throw Error('Dynamic require of "' + x + '" is not supported'); | ||
}); | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
// If the importer is in node compatibility mode or this is not an ESM | ||
// file that has been converted to a CommonJS file using a Babel- | ||
// compatible transform (i.e. "__esModule" has not been set), then set | ||
// "default" to the CommonJS "module.exports" for node compatibility. | ||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
mod | ||
)); | ||
var __create = Object.create; | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
// If the importer is in node compatibility mode or this is not an ESM | ||
// file that has been converted to a CommonJS file using a Babel- | ||
// compatible transform (i.e. "__esModule" has not been set), then set | ||
// "default" to the CommonJS "module.exports" for node compatibility. | ||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
mod | ||
)); | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
// src/index.tsx | ||
var import_react4 = __toESM(__require("react")); | ||
var import_react_fast_compare = __toESM(__require("react-fast-compare")); | ||
var import_invariant = __toESM(__require("invariant")); | ||
// src/index.tsx | ||
var src_exports = {}; | ||
__export(src_exports, { | ||
Helmet: () => Helmet, | ||
HelmetData: () => HelmetData, | ||
HelmetProvider: () => HelmetProvider | ||
}); | ||
module.exports = __toCommonJS(src_exports); | ||
var import_react4 = __toESM(require("react")); | ||
var import_react_fast_compare = __toESM(require("react-fast-compare")); | ||
var import_invariant = __toESM(require("invariant")); | ||
// src/Provider.tsx | ||
var import_react2 = __toESM(__require("react")); | ||
// src/Provider.tsx | ||
var import_react2 = __toESM(require("react")); | ||
// src/server.ts | ||
var import_react = __toESM(__require("react")); | ||
// src/server.ts | ||
var import_react = __toESM(require("react")); | ||
// src/constants.ts | ||
var TAG_NAMES = /* @__PURE__ */ ((TAG_NAMES2) => { | ||
TAG_NAMES2["BASE"] = "base"; | ||
TAG_NAMES2["BODY"] = "body"; | ||
TAG_NAMES2["HEAD"] = "head"; | ||
TAG_NAMES2["HTML"] = "html"; | ||
TAG_NAMES2["LINK"] = "link"; | ||
TAG_NAMES2["META"] = "meta"; | ||
TAG_NAMES2["NOSCRIPT"] = "noscript"; | ||
TAG_NAMES2["SCRIPT"] = "script"; | ||
TAG_NAMES2["STYLE"] = "style"; | ||
TAG_NAMES2["TITLE"] = "title"; | ||
TAG_NAMES2["FRAGMENT"] = "Symbol(react.fragment)"; | ||
return TAG_NAMES2; | ||
})(TAG_NAMES || {}); | ||
var SEO_PRIORITY_TAGS = { | ||
link: { rel: ["amphtml", "canonical", "alternate"] }, | ||
script: { type: ["application/ld+json"] }, | ||
meta: { | ||
charset: "", | ||
name: ["generator", "robots", "description"], | ||
property: [ | ||
"og:type", | ||
"og:title", | ||
"og:url", | ||
"og:image", | ||
"og:image:alt", | ||
"og:description", | ||
"twitter:url", | ||
"twitter:title", | ||
"twitter:description", | ||
"twitter:image", | ||
"twitter:image:alt", | ||
"twitter:card", | ||
"twitter:site" | ||
] | ||
// src/constants.ts | ||
var TAG_NAMES = /* @__PURE__ */ ((TAG_NAMES2) => { | ||
TAG_NAMES2["BASE"] = "base"; | ||
TAG_NAMES2["BODY"] = "body"; | ||
TAG_NAMES2["HEAD"] = "head"; | ||
TAG_NAMES2["HTML"] = "html"; | ||
TAG_NAMES2["LINK"] = "link"; | ||
TAG_NAMES2["META"] = "meta"; | ||
TAG_NAMES2["NOSCRIPT"] = "noscript"; | ||
TAG_NAMES2["SCRIPT"] = "script"; | ||
TAG_NAMES2["STYLE"] = "style"; | ||
TAG_NAMES2["TITLE"] = "title"; | ||
TAG_NAMES2["FRAGMENT"] = "Symbol(react.fragment)"; | ||
return TAG_NAMES2; | ||
})(TAG_NAMES || {}); | ||
var SEO_PRIORITY_TAGS = { | ||
link: { rel: ["amphtml", "canonical", "alternate"] }, | ||
script: { type: ["application/ld+json"] }, | ||
meta: { | ||
charset: "", | ||
name: ["generator", "robots", "description"], | ||
property: [ | ||
"og:type", | ||
"og:title", | ||
"og:url", | ||
"og:image", | ||
"og:image:alt", | ||
"og:description", | ||
"twitter:url", | ||
"twitter:title", | ||
"twitter:description", | ||
"twitter:image", | ||
"twitter:image:alt", | ||
"twitter:card", | ||
"twitter:site" | ||
] | ||
} | ||
}; | ||
var VALID_TAG_NAMES = Object.values(TAG_NAMES); | ||
var REACT_TAG_MAP = { | ||
accesskey: "accessKey", | ||
charset: "charSet", | ||
class: "className", | ||
contenteditable: "contentEditable", | ||
contextmenu: "contextMenu", | ||
"http-equiv": "httpEquiv", | ||
itemprop: "itemProp", | ||
tabindex: "tabIndex" | ||
}; | ||
var HTML_TAG_MAP = Object.entries(REACT_TAG_MAP).reduce( | ||
(carry, [key, value]) => { | ||
carry[value] = key; | ||
return carry; | ||
}, | ||
{} | ||
); | ||
var HELMET_ATTRIBUTE = "data-rh"; | ||
// src/utils.ts | ||
var HELMET_PROPS = { | ||
DEFAULT_TITLE: "defaultTitle", | ||
DEFER: "defer", | ||
ENCODE_SPECIAL_CHARACTERS: "encodeSpecialCharacters", | ||
ON_CHANGE_CLIENT_STATE: "onChangeClientState", | ||
TITLE_TEMPLATE: "titleTemplate", | ||
PRIORITIZE_SEO_TAGS: "prioritizeSeoTags" | ||
}; | ||
var getInnermostProperty = (propsList, property) => { | ||
for (let i = propsList.length - 1; i >= 0; i -= 1) { | ||
const props = propsList[i]; | ||
if (Object.prototype.hasOwnProperty.call(props, property)) { | ||
return props[property]; | ||
} | ||
}; | ||
var VALID_TAG_NAMES = Object.values(TAG_NAMES); | ||
var REACT_TAG_MAP = { | ||
accesskey: "accessKey", | ||
charset: "charSet", | ||
class: "className", | ||
contenteditable: "contentEditable", | ||
contextmenu: "contextMenu", | ||
"http-equiv": "httpEquiv", | ||
itemprop: "itemProp", | ||
tabindex: "tabIndex" | ||
}; | ||
var HTML_TAG_MAP = Object.entries(REACT_TAG_MAP).reduce( | ||
(carry, [key, value]) => { | ||
carry[value] = key; | ||
return carry; | ||
}, | ||
{} | ||
); | ||
var HELMET_ATTRIBUTE = "data-rh"; | ||
// src/utils.ts | ||
var HELMET_PROPS = { | ||
DEFAULT_TITLE: "defaultTitle", | ||
DEFER: "defer", | ||
ENCODE_SPECIAL_CHARACTERS: "encodeSpecialCharacters", | ||
ON_CHANGE_CLIENT_STATE: "onChangeClientState", | ||
TITLE_TEMPLATE: "titleTemplate", | ||
PRIORITIZE_SEO_TAGS: "prioritizeSeoTags" | ||
}; | ||
var getInnermostProperty = (propsList, property) => { | ||
for (let i = propsList.length - 1; i >= 0; i -= 1) { | ||
const props = propsList[i]; | ||
if (Object.prototype.hasOwnProperty.call(props, property)) { | ||
return props[property]; | ||
} | ||
return null; | ||
}; | ||
var getTitleFromPropsList = (propsList) => { | ||
let innermostTitle = getInnermostProperty(propsList, "title" /* TITLE */); | ||
const innermostTemplate = getInnermostProperty(propsList, HELMET_PROPS.TITLE_TEMPLATE); | ||
if (Array.isArray(innermostTitle)) { | ||
innermostTitle = innermostTitle.join(""); | ||
} | ||
if (innermostTemplate && innermostTitle) { | ||
return innermostTemplate.replace(/%s/g, () => innermostTitle); | ||
} | ||
const innermostDefaultTitle = getInnermostProperty(propsList, HELMET_PROPS.DEFAULT_TITLE); | ||
return innermostTitle || innermostDefaultTitle || void 0; | ||
}; | ||
var getOnChangeClientState = (propsList) => getInnermostProperty(propsList, HELMET_PROPS.ON_CHANGE_CLIENT_STATE) || (() => { | ||
}); | ||
var getAttributesFromPropsList = (tagType, propsList) => propsList.filter((props) => typeof props[tagType] !== "undefined").map((props) => props[tagType]).reduce((tagAttrs, current) => ({ ...tagAttrs, ...current }), {}); | ||
var getBaseTagFromPropsList = (primaryAttributes, propsList) => propsList.filter((props) => typeof props["base" /* BASE */] !== "undefined").map((props) => props["base" /* BASE */]).reverse().reduce((innermostBaseTag, tag) => { | ||
if (!innermostBaseTag.length) { | ||
const keys = Object.keys(tag); | ||
for (let i = 0; i < keys.length; i += 1) { | ||
const attributeKey = keys[i]; | ||
const lowerCaseAttributeKey = attributeKey.toLowerCase(); | ||
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && tag[lowerCaseAttributeKey]) { | ||
return innermostBaseTag.concat(tag); | ||
} | ||
} | ||
return null; | ||
}; | ||
var getTitleFromPropsList = (propsList) => { | ||
let innermostTitle = getInnermostProperty(propsList, "title" /* TITLE */); | ||
const innermostTemplate = getInnermostProperty(propsList, HELMET_PROPS.TITLE_TEMPLATE); | ||
if (Array.isArray(innermostTitle)) { | ||
innermostTitle = innermostTitle.join(""); | ||
} | ||
return innermostBaseTag; | ||
}, []); | ||
var warn = (msg) => console && typeof console.warn === "function" && console.warn(msg); | ||
var getTagsFromPropsList = (tagName, primaryAttributes, propsList) => { | ||
const approvedSeenTags = {}; | ||
return propsList.filter((props) => { | ||
if (Array.isArray(props[tagName])) { | ||
return true; | ||
} | ||
if (innermostTemplate && innermostTitle) { | ||
return innermostTemplate.replace(/%s/g, () => innermostTitle); | ||
if (typeof props[tagName] !== "undefined") { | ||
warn( | ||
`Helmet: ${tagName} should be of type "Array". Instead found type "${typeof props[tagName]}"` | ||
); | ||
} | ||
const innermostDefaultTitle = getInnermostProperty(propsList, HELMET_PROPS.DEFAULT_TITLE); | ||
return innermostTitle || innermostDefaultTitle || void 0; | ||
}; | ||
var getOnChangeClientState = (propsList) => getInnermostProperty(propsList, HELMET_PROPS.ON_CHANGE_CLIENT_STATE) || (() => { | ||
}); | ||
var getAttributesFromPropsList = (tagType, propsList) => propsList.filter((props) => typeof props[tagType] !== "undefined").map((props) => props[tagType]).reduce((tagAttrs, current) => ({ ...tagAttrs, ...current }), {}); | ||
var getBaseTagFromPropsList = (primaryAttributes, propsList) => propsList.filter((props) => typeof props["base" /* BASE */] !== "undefined").map((props) => props["base" /* BASE */]).reverse().reduce((innermostBaseTag, tag) => { | ||
if (!innermostBaseTag.length) { | ||
const keys = Object.keys(tag); | ||
for (let i = 0; i < keys.length; i += 1) { | ||
const attributeKey = keys[i]; | ||
return false; | ||
}).map((props) => props[tagName]).reverse().reduce((approvedTags, instanceTags) => { | ||
const instanceSeenTags = {}; | ||
instanceTags.filter((tag) => { | ||
let primaryAttributeKey; | ||
const keys2 = Object.keys(tag); | ||
for (let i = 0; i < keys2.length; i += 1) { | ||
const attributeKey = keys2[i]; | ||
const lowerCaseAttributeKey = attributeKey.toLowerCase(); | ||
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && tag[lowerCaseAttributeKey]) { | ||
return innermostBaseTag.concat(tag); | ||
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && !(primaryAttributeKey === "rel" /* REL */ && tag[primaryAttributeKey].toLowerCase() === "canonical") && !(lowerCaseAttributeKey === "rel" /* REL */ && tag[lowerCaseAttributeKey].toLowerCase() === "stylesheet")) { | ||
primaryAttributeKey = lowerCaseAttributeKey; | ||
} | ||
if (primaryAttributes.indexOf(attributeKey) !== -1 && (attributeKey === "innerHTML" /* INNER_HTML */ || attributeKey === "cssText" /* CSS_TEXT */ || attributeKey === "itemprop" /* ITEM_PROP */)) { | ||
primaryAttributeKey = attributeKey; | ||
} | ||
} | ||
} | ||
return innermostBaseTag; | ||
}, []); | ||
var warn = (msg) => console && typeof console.warn === "function" && console.warn(msg); | ||
var getTagsFromPropsList = (tagName, primaryAttributes, propsList) => { | ||
const approvedSeenTags = {}; | ||
return propsList.filter((props) => { | ||
if (Array.isArray(props[tagName])) { | ||
return true; | ||
if (!primaryAttributeKey || !tag[primaryAttributeKey]) { | ||
return false; | ||
} | ||
if (typeof props[tagName] !== "undefined") { | ||
warn( | ||
`Helmet: ${tagName} should be of type "Array". Instead found type "${typeof props[tagName]}"` | ||
); | ||
const value = tag[primaryAttributeKey].toLowerCase(); | ||
if (!approvedSeenTags[primaryAttributeKey]) { | ||
approvedSeenTags[primaryAttributeKey] = {}; | ||
} | ||
return false; | ||
}).map((props) => props[tagName]).reverse().reduce((approvedTags, instanceTags) => { | ||
const instanceSeenTags = {}; | ||
instanceTags.filter((tag) => { | ||
let primaryAttributeKey; | ||
const keys2 = Object.keys(tag); | ||
for (let i = 0; i < keys2.length; i += 1) { | ||
const attributeKey = keys2[i]; | ||
const lowerCaseAttributeKey = attributeKey.toLowerCase(); | ||
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && !(primaryAttributeKey === "rel" /* REL */ && tag[primaryAttributeKey].toLowerCase() === "canonical") && !(lowerCaseAttributeKey === "rel" /* REL */ && tag[lowerCaseAttributeKey].toLowerCase() === "stylesheet")) { | ||
primaryAttributeKey = lowerCaseAttributeKey; | ||
} | ||
if (primaryAttributes.indexOf(attributeKey) !== -1 && (attributeKey === "innerHTML" /* INNER_HTML */ || attributeKey === "cssText" /* CSS_TEXT */ || attributeKey === "itemprop" /* ITEM_PROP */)) { | ||
primaryAttributeKey = attributeKey; | ||
} | ||
} | ||
if (!primaryAttributeKey || !tag[primaryAttributeKey]) { | ||
return false; | ||
} | ||
const value = tag[primaryAttributeKey].toLowerCase(); | ||
if (!approvedSeenTags[primaryAttributeKey]) { | ||
approvedSeenTags[primaryAttributeKey] = {}; | ||
} | ||
if (!instanceSeenTags[primaryAttributeKey]) { | ||
instanceSeenTags[primaryAttributeKey] = {}; | ||
} | ||
if (!approvedSeenTags[primaryAttributeKey][value]) { | ||
instanceSeenTags[primaryAttributeKey][value] = true; | ||
return true; | ||
} | ||
return false; | ||
}).reverse().forEach((tag) => approvedTags.push(tag)); | ||
const keys = Object.keys(instanceSeenTags); | ||
for (let i = 0; i < keys.length; i += 1) { | ||
const attributeKey = keys[i]; | ||
const tagUnion = { | ||
...approvedSeenTags[attributeKey], | ||
...instanceSeenTags[attributeKey] | ||
}; | ||
approvedSeenTags[attributeKey] = tagUnion; | ||
if (!instanceSeenTags[primaryAttributeKey]) { | ||
instanceSeenTags[primaryAttributeKey] = {}; | ||
} | ||
return approvedTags; | ||
}, []).reverse(); | ||
}; | ||
var getAnyTrueFromPropsList = (propsList, checkedTag) => { | ||
if (Array.isArray(propsList) && propsList.length) { | ||
for (let index = 0; index < propsList.length; index += 1) { | ||
const prop = propsList[index]; | ||
if (prop[checkedTag]) { | ||
return true; | ||
} | ||
if (!approvedSeenTags[primaryAttributeKey][value]) { | ||
instanceSeenTags[primaryAttributeKey][value] = true; | ||
return true; | ||
} | ||
return false; | ||
}).reverse().forEach((tag) => approvedTags.push(tag)); | ||
const keys = Object.keys(instanceSeenTags); | ||
for (let i = 0; i < keys.length; i += 1) { | ||
const attributeKey = keys[i]; | ||
const tagUnion = { | ||
...approvedSeenTags[attributeKey], | ||
...instanceSeenTags[attributeKey] | ||
}; | ||
approvedSeenTags[attributeKey] = tagUnion; | ||
} | ||
return false; | ||
}; | ||
var reducePropsToState = (propsList) => ({ | ||
baseTag: getBaseTagFromPropsList(["href" /* HREF */], propsList), | ||
bodyAttributes: getAttributesFromPropsList("bodyAttributes" /* BODY */, propsList), | ||
defer: getInnermostProperty(propsList, HELMET_PROPS.DEFER), | ||
encode: getInnermostProperty(propsList, HELMET_PROPS.ENCODE_SPECIAL_CHARACTERS), | ||
htmlAttributes: getAttributesFromPropsList("htmlAttributes" /* HTML */, propsList), | ||
linkTags: getTagsFromPropsList( | ||
"link" /* LINK */, | ||
["rel" /* REL */, "href" /* HREF */], | ||
propsList | ||
), | ||
metaTags: getTagsFromPropsList( | ||
"meta" /* META */, | ||
[ | ||
"name" /* NAME */, | ||
"charset" /* CHARSET */, | ||
"http-equiv" /* HTTPEQUIV */, | ||
"property" /* PROPERTY */, | ||
"itemprop" /* ITEM_PROP */ | ||
], | ||
propsList | ||
), | ||
noscriptTags: getTagsFromPropsList("noscript" /* NOSCRIPT */, ["innerHTML" /* INNER_HTML */], propsList), | ||
onChangeClientState: getOnChangeClientState(propsList), | ||
scriptTags: getTagsFromPropsList( | ||
"script" /* SCRIPT */, | ||
["src" /* SRC */, "innerHTML" /* INNER_HTML */], | ||
propsList | ||
), | ||
styleTags: getTagsFromPropsList("style" /* STYLE */, ["cssText" /* CSS_TEXT */], propsList), | ||
title: getTitleFromPropsList(propsList), | ||
titleAttributes: getAttributesFromPropsList("titleAttributes" /* TITLE */, propsList), | ||
prioritizeSeoTags: getAnyTrueFromPropsList(propsList, HELMET_PROPS.PRIORITIZE_SEO_TAGS) | ||
}); | ||
var flattenArray = (possibleArray) => Array.isArray(possibleArray) ? possibleArray.join("") : possibleArray; | ||
var checkIfPropsMatch = (props, toMatch) => { | ||
const keys = Object.keys(props); | ||
for (let i = 0; i < keys.length; i += 1) { | ||
if (toMatch[keys[i]] && toMatch[keys[i]].includes(props[keys[i]])) { | ||
return approvedTags; | ||
}, []).reverse(); | ||
}; | ||
var getAnyTrueFromPropsList = (propsList, checkedTag) => { | ||
if (Array.isArray(propsList) && propsList.length) { | ||
for (let index = 0; index < propsList.length; index += 1) { | ||
const prop = propsList[index]; | ||
if (prop[checkedTag]) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
var prioritizer = (elementsList, propsToMatch) => { | ||
if (Array.isArray(elementsList)) { | ||
return elementsList.reduce( | ||
(acc, elementAttrs) => { | ||
if (checkIfPropsMatch(elementAttrs, propsToMatch)) { | ||
acc.priority.push(elementAttrs); | ||
} else { | ||
acc.default.push(elementAttrs); | ||
} | ||
return acc; | ||
}, | ||
{ priority: [], default: [] } | ||
); | ||
} | ||
return false; | ||
}; | ||
var reducePropsToState = (propsList) => ({ | ||
baseTag: getBaseTagFromPropsList(["href" /* HREF */], propsList), | ||
bodyAttributes: getAttributesFromPropsList("bodyAttributes" /* BODY */, propsList), | ||
defer: getInnermostProperty(propsList, HELMET_PROPS.DEFER), | ||
encode: getInnermostProperty(propsList, HELMET_PROPS.ENCODE_SPECIAL_CHARACTERS), | ||
htmlAttributes: getAttributesFromPropsList("htmlAttributes" /* HTML */, propsList), | ||
linkTags: getTagsFromPropsList( | ||
"link" /* LINK */, | ||
["rel" /* REL */, "href" /* HREF */], | ||
propsList | ||
), | ||
metaTags: getTagsFromPropsList( | ||
"meta" /* META */, | ||
[ | ||
"name" /* NAME */, | ||
"charset" /* CHARSET */, | ||
"http-equiv" /* HTTPEQUIV */, | ||
"property" /* PROPERTY */, | ||
"itemprop" /* ITEM_PROP */ | ||
], | ||
propsList | ||
), | ||
noscriptTags: getTagsFromPropsList("noscript" /* NOSCRIPT */, ["innerHTML" /* INNER_HTML */], propsList), | ||
onChangeClientState: getOnChangeClientState(propsList), | ||
scriptTags: getTagsFromPropsList( | ||
"script" /* SCRIPT */, | ||
["src" /* SRC */, "innerHTML" /* INNER_HTML */], | ||
propsList | ||
), | ||
styleTags: getTagsFromPropsList("style" /* STYLE */, ["cssText" /* CSS_TEXT */], propsList), | ||
title: getTitleFromPropsList(propsList), | ||
titleAttributes: getAttributesFromPropsList("titleAttributes" /* TITLE */, propsList), | ||
prioritizeSeoTags: getAnyTrueFromPropsList(propsList, HELMET_PROPS.PRIORITIZE_SEO_TAGS) | ||
}); | ||
var flattenArray = (possibleArray) => Array.isArray(possibleArray) ? possibleArray.join("") : possibleArray; | ||
var checkIfPropsMatch = (props, toMatch) => { | ||
const keys = Object.keys(props); | ||
for (let i = 0; i < keys.length; i += 1) { | ||
if (toMatch[keys[i]] && toMatch[keys[i]].includes(props[keys[i]])) { | ||
return true; | ||
} | ||
return { default: elementsList, priority: [] }; | ||
} | ||
return false; | ||
}; | ||
var prioritizer = (elementsList, propsToMatch) => { | ||
if (Array.isArray(elementsList)) { | ||
return elementsList.reduce( | ||
(acc, elementAttrs) => { | ||
if (checkIfPropsMatch(elementAttrs, propsToMatch)) { | ||
acc.priority.push(elementAttrs); | ||
} else { | ||
acc.default.push(elementAttrs); | ||
} | ||
return acc; | ||
}, | ||
{ priority: [], default: [] } | ||
); | ||
} | ||
return { default: elementsList, priority: [] }; | ||
}; | ||
var without = (obj, key) => { | ||
return { | ||
...obj, | ||
[key]: void 0 | ||
}; | ||
var without = (obj, key) => { | ||
return { | ||
...obj, | ||
[key]: void 0 | ||
}; | ||
}; | ||
}; | ||
// src/server.ts | ||
var SELF_CLOSING_TAGS = ["noscript" /* NOSCRIPT */, "script" /* SCRIPT */, "style" /* STYLE */]; | ||
var encodeSpecialCharacters = (str, encode = true) => { | ||
if (encode === false) { | ||
return String(str); | ||
} | ||
return String(str).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
}; | ||
var generateElementAttributesAsString = (attributes) => Object.keys(attributes).reduce((str, key) => { | ||
const attr = typeof attributes[key] !== "undefined" ? `${key}="${attributes[key]}"` : `${key}`; | ||
return str ? `${str} ${attr}` : attr; | ||
// src/server.ts | ||
var SELF_CLOSING_TAGS = ["noscript" /* NOSCRIPT */, "script" /* SCRIPT */, "style" /* STYLE */]; | ||
var encodeSpecialCharacters = (str, encode = true) => { | ||
if (encode === false) { | ||
return String(str); | ||
} | ||
return String(str).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
}; | ||
var generateElementAttributesAsString = (attributes) => Object.keys(attributes).reduce((str, key) => { | ||
const attr = typeof attributes[key] !== "undefined" ? `${key}="${attributes[key]}"` : `${key}`; | ||
return str ? `${str} ${attr}` : attr; | ||
}, ""); | ||
var generateTitleAsString = (type, title, attributes, encode) => { | ||
const attributeString = generateElementAttributesAsString(attributes); | ||
const flattenedTitle = flattenArray(title); | ||
return attributeString ? `<${type} ${HELMET_ATTRIBUTE}="true" ${attributeString}>${encodeSpecialCharacters( | ||
flattenedTitle, | ||
encode | ||
)}</${type}>` : `<${type} ${HELMET_ATTRIBUTE}="true">${encodeSpecialCharacters( | ||
flattenedTitle, | ||
encode | ||
)}</${type}>`; | ||
}; | ||
var generateTagsAsString = (type, tags, encode = true) => tags.reduce((str, t) => { | ||
const tag = t; | ||
const attributeHtml = Object.keys(tag).filter( | ||
(attribute) => !(attribute === "innerHTML" /* INNER_HTML */ || attribute === "cssText" /* CSS_TEXT */) | ||
).reduce((string, attribute) => { | ||
const attr = typeof tag[attribute] === "undefined" ? attribute : `${attribute}="${encodeSpecialCharacters(tag[attribute], encode)}"`; | ||
return string ? `${string} ${attr}` : attr; | ||
}, ""); | ||
var generateTitleAsString = (type, title, attributes, encode) => { | ||
const attributeString = generateElementAttributesAsString(attributes); | ||
const flattenedTitle = flattenArray(title); | ||
return attributeString ? `<${type} ${HELMET_ATTRIBUTE}="true" ${attributeString}>${encodeSpecialCharacters( | ||
flattenedTitle, | ||
encode | ||
)}</${type}>` : `<${type} ${HELMET_ATTRIBUTE}="true">${encodeSpecialCharacters( | ||
flattenedTitle, | ||
encode | ||
)}</${type}>`; | ||
const tagContent = tag.innerHTML || tag.cssText || ""; | ||
const isSelfClosing = SELF_CLOSING_TAGS.indexOf(type) === -1; | ||
return `${str}<${type} ${HELMET_ATTRIBUTE}="true" ${attributeHtml}${isSelfClosing ? `/>` : `>${tagContent}</${type}>`}`; | ||
}, ""); | ||
var convertElementAttributesToReactProps = (attributes, initProps = {}) => Object.keys(attributes).reduce((obj, key) => { | ||
const mapped = REACT_TAG_MAP[key]; | ||
obj[mapped || key] = attributes[key]; | ||
return obj; | ||
}, initProps); | ||
var generateTitleAsReactComponent = (_type, title, attributes) => { | ||
const initProps = { | ||
key: title, | ||
[HELMET_ATTRIBUTE]: true | ||
}; | ||
var generateTagsAsString = (type, tags, encode = true) => tags.reduce((str, t) => { | ||
const tag = t; | ||
const attributeHtml = Object.keys(tag).filter( | ||
(attribute) => !(attribute === "innerHTML" /* INNER_HTML */ || attribute === "cssText" /* CSS_TEXT */) | ||
).reduce((string, attribute) => { | ||
const attr = typeof tag[attribute] === "undefined" ? attribute : `${attribute}="${encodeSpecialCharacters(tag[attribute], encode)}"`; | ||
return string ? `${string} ${attr}` : attr; | ||
}, ""); | ||
const tagContent = tag.innerHTML || tag.cssText || ""; | ||
const isSelfClosing = SELF_CLOSING_TAGS.indexOf(type) === -1; | ||
return `${str}<${type} ${HELMET_ATTRIBUTE}="true" ${attributeHtml}${isSelfClosing ? `/>` : `>${tagContent}</${type}>`}`; | ||
}, ""); | ||
var convertElementAttributesToReactProps = (attributes, initProps = {}) => Object.keys(attributes).reduce((obj, key) => { | ||
const mapped = REACT_TAG_MAP[key]; | ||
obj[mapped || key] = attributes[key]; | ||
return obj; | ||
}, initProps); | ||
var generateTitleAsReactComponent = (_type, title, attributes) => { | ||
const initProps = { | ||
key: title, | ||
[HELMET_ATTRIBUTE]: true | ||
}; | ||
const props = convertElementAttributesToReactProps(attributes, initProps); | ||
return [import_react.default.createElement("title" /* TITLE */, props, title)]; | ||
const props = convertElementAttributesToReactProps(attributes, initProps); | ||
return [import_react.default.createElement("title" /* TITLE */, props, title)]; | ||
}; | ||
var generateTagsAsReactComponent = (type, tags) => tags.map((tag, i) => { | ||
const mappedTag = { | ||
key: i, | ||
[HELMET_ATTRIBUTE]: true | ||
}; | ||
var generateTagsAsReactComponent = (type, tags) => tags.map((tag, i) => { | ||
const mappedTag = { | ||
key: i, | ||
[HELMET_ATTRIBUTE]: true | ||
}; | ||
Object.keys(tag).forEach((attribute) => { | ||
const mapped = REACT_TAG_MAP[attribute]; | ||
const mappedAttribute = mapped || attribute; | ||
if (mappedAttribute === "innerHTML" /* INNER_HTML */ || mappedAttribute === "cssText" /* CSS_TEXT */) { | ||
const content = tag.innerHTML || tag.cssText; | ||
mappedTag.dangerouslySetInnerHTML = { __html: content }; | ||
} else { | ||
mappedTag[mappedAttribute] = tag[attribute]; | ||
} | ||
}); | ||
return import_react.default.createElement(type, mappedTag); | ||
Object.keys(tag).forEach((attribute) => { | ||
const mapped = REACT_TAG_MAP[attribute]; | ||
const mappedAttribute = mapped || attribute; | ||
if (mappedAttribute === "innerHTML" /* INNER_HTML */ || mappedAttribute === "cssText" /* CSS_TEXT */) { | ||
const content = tag.innerHTML || tag.cssText; | ||
mappedTag.dangerouslySetInnerHTML = { __html: content }; | ||
} else { | ||
mappedTag[mappedAttribute] = tag[attribute]; | ||
} | ||
}); | ||
var getMethodsForTag = (type, tags, encode = true) => { | ||
switch (type) { | ||
case "title" /* TITLE */: | ||
return { | ||
toComponent: () => generateTitleAsReactComponent(type, tags.title, tags.titleAttributes), | ||
toString: () => generateTitleAsString(type, tags.title, tags.titleAttributes, encode) | ||
}; | ||
case "bodyAttributes" /* BODY */: | ||
case "htmlAttributes" /* HTML */: | ||
return { | ||
toComponent: () => convertElementAttributesToReactProps(tags), | ||
toString: () => generateElementAttributesAsString(tags) | ||
}; | ||
default: | ||
return { | ||
toComponent: () => generateTagsAsReactComponent(type, tags), | ||
toString: () => generateTagsAsString(type, tags, encode) | ||
}; | ||
} | ||
return import_react.default.createElement(type, mappedTag); | ||
}); | ||
var getMethodsForTag = (type, tags, encode = true) => { | ||
switch (type) { | ||
case "title" /* TITLE */: | ||
return { | ||
toComponent: () => generateTitleAsReactComponent(type, tags.title, tags.titleAttributes), | ||
toString: () => generateTitleAsString(type, tags.title, tags.titleAttributes, encode) | ||
}; | ||
case "bodyAttributes" /* BODY */: | ||
case "htmlAttributes" /* HTML */: | ||
return { | ||
toComponent: () => convertElementAttributesToReactProps(tags), | ||
toString: () => generateElementAttributesAsString(tags) | ||
}; | ||
default: | ||
return { | ||
toComponent: () => generateTagsAsReactComponent(type, tags), | ||
toString: () => generateTagsAsString(type, tags, encode) | ||
}; | ||
} | ||
}; | ||
var getPriorityMethods = ({ metaTags, linkTags, scriptTags, encode }) => { | ||
const meta = prioritizer(metaTags, SEO_PRIORITY_TAGS.meta); | ||
const link = prioritizer(linkTags, SEO_PRIORITY_TAGS.link); | ||
const script = prioritizer(scriptTags, SEO_PRIORITY_TAGS.script); | ||
const priorityMethods = { | ||
toComponent: () => [ | ||
...generateTagsAsReactComponent("meta" /* META */, meta.priority), | ||
...generateTagsAsReactComponent("link" /* LINK */, link.priority), | ||
...generateTagsAsReactComponent("script" /* SCRIPT */, script.priority) | ||
], | ||
toString: () => ( | ||
// generate all the tags as strings and concatenate them | ||
`${getMethodsForTag("meta" /* META */, meta.priority, encode)} ${getMethodsForTag( | ||
"link" /* LINK */, | ||
link.priority, | ||
encode | ||
)} ${getMethodsForTag("script" /* SCRIPT */, script.priority, encode)}` | ||
) | ||
}; | ||
var getPriorityMethods = ({ metaTags, linkTags, scriptTags, encode }) => { | ||
const meta = prioritizer(metaTags, SEO_PRIORITY_TAGS.meta); | ||
const link = prioritizer(linkTags, SEO_PRIORITY_TAGS.link); | ||
const script = prioritizer(scriptTags, SEO_PRIORITY_TAGS.script); | ||
const priorityMethods = { | ||
toComponent: () => [ | ||
...generateTagsAsReactComponent("meta" /* META */, meta.priority), | ||
...generateTagsAsReactComponent("link" /* LINK */, link.priority), | ||
...generateTagsAsReactComponent("script" /* SCRIPT */, script.priority) | ||
], | ||
toString: () => ( | ||
// generate all the tags as strings and concatenate them | ||
`${getMethodsForTag("meta" /* META */, meta.priority, encode)} ${getMethodsForTag( | ||
"link" /* LINK */, | ||
link.priority, | ||
encode | ||
)} ${getMethodsForTag("script" /* SCRIPT */, script.priority, encode)}` | ||
) | ||
}; | ||
return { | ||
priorityMethods, | ||
metaTags: meta.default, | ||
linkTags: link.default, | ||
scriptTags: script.default | ||
}; | ||
return { | ||
priorityMethods, | ||
metaTags: meta.default, | ||
linkTags: link.default, | ||
scriptTags: script.default | ||
}; | ||
var mapStateOnServer = (props) => { | ||
const { | ||
baseTag, | ||
bodyAttributes, | ||
encode = true, | ||
htmlAttributes, | ||
noscriptTags, | ||
styleTags, | ||
title = "", | ||
titleAttributes, | ||
prioritizeSeoTags | ||
} = props; | ||
let { linkTags, metaTags, scriptTags } = props; | ||
let priorityMethods = { | ||
toComponent: () => { | ||
}, | ||
toString: () => "" | ||
}; | ||
if (prioritizeSeoTags) { | ||
({ priorityMethods, linkTags, metaTags, scriptTags } = getPriorityMethods(props)); | ||
} | ||
return { | ||
priority: priorityMethods, | ||
base: getMethodsForTag("base" /* BASE */, baseTag, encode), | ||
bodyAttributes: getMethodsForTag("bodyAttributes" /* BODY */, bodyAttributes, encode), | ||
htmlAttributes: getMethodsForTag("htmlAttributes" /* HTML */, htmlAttributes, encode), | ||
link: getMethodsForTag("link" /* LINK */, linkTags, encode), | ||
meta: getMethodsForTag("meta" /* META */, metaTags, encode), | ||
noscript: getMethodsForTag("noscript" /* NOSCRIPT */, noscriptTags, encode), | ||
script: getMethodsForTag("script" /* SCRIPT */, scriptTags, encode), | ||
style: getMethodsForTag("style" /* STYLE */, styleTags, encode), | ||
title: getMethodsForTag("title" /* TITLE */, { title, titleAttributes }, encode) | ||
}; | ||
}; | ||
var mapStateOnServer = (props) => { | ||
const { | ||
baseTag, | ||
bodyAttributes, | ||
encode = true, | ||
htmlAttributes, | ||
noscriptTags, | ||
styleTags, | ||
title = "", | ||
titleAttributes, | ||
prioritizeSeoTags | ||
} = props; | ||
let { linkTags, metaTags, scriptTags } = props; | ||
let priorityMethods = { | ||
toComponent: () => { | ||
}, | ||
toString: () => "" | ||
}; | ||
var server_default = mapStateOnServer; | ||
if (prioritizeSeoTags) { | ||
({ priorityMethods, linkTags, metaTags, scriptTags } = getPriorityMethods(props)); | ||
} | ||
return { | ||
priority: priorityMethods, | ||
base: getMethodsForTag("base" /* BASE */, baseTag, encode), | ||
bodyAttributes: getMethodsForTag("bodyAttributes" /* BODY */, bodyAttributes, encode), | ||
htmlAttributes: getMethodsForTag("htmlAttributes" /* HTML */, htmlAttributes, encode), | ||
link: getMethodsForTag("link" /* LINK */, linkTags, encode), | ||
meta: getMethodsForTag("meta" /* META */, metaTags, encode), | ||
noscript: getMethodsForTag("noscript" /* NOSCRIPT */, noscriptTags, encode), | ||
script: getMethodsForTag("script" /* SCRIPT */, scriptTags, encode), | ||
style: getMethodsForTag("style" /* STYLE */, styleTags, encode), | ||
title: getMethodsForTag("title" /* TITLE */, { title, titleAttributes }, encode) | ||
}; | ||
}; | ||
var server_default = mapStateOnServer; | ||
// src/HelmetData.ts | ||
var instances = []; | ||
var HelmetData = class { | ||
instances = []; | ||
canUseDOM = typeof document !== "undefined"; | ||
context; | ||
value = { | ||
setHelmet: (serverState) => { | ||
this.context.helmet = serverState; | ||
// src/HelmetData.ts | ||
var instances = []; | ||
var HelmetData = class { | ||
instances = []; | ||
canUseDOM = typeof document !== "undefined"; | ||
context; | ||
value = { | ||
setHelmet: (serverState) => { | ||
this.context.helmet = serverState; | ||
}, | ||
helmetInstances: { | ||
get: () => this.canUseDOM ? instances : this.instances, | ||
add: (instance) => { | ||
(this.canUseDOM ? instances : this.instances).push(instance); | ||
}, | ||
helmetInstances: { | ||
get: () => this.canUseDOM ? instances : this.instances, | ||
add: (instance) => { | ||
(this.canUseDOM ? instances : this.instances).push(instance); | ||
}, | ||
remove: (instance) => { | ||
const index = (this.canUseDOM ? instances : this.instances).indexOf(instance); | ||
(this.canUseDOM ? instances : this.instances).splice(index, 1); | ||
} | ||
remove: (instance) => { | ||
const index = (this.canUseDOM ? instances : this.instances).indexOf(instance); | ||
(this.canUseDOM ? instances : this.instances).splice(index, 1); | ||
} | ||
}; | ||
constructor(context, canUseDOM2) { | ||
this.context = context; | ||
this.canUseDOM = canUseDOM2 || false; | ||
if (!canUseDOM2) { | ||
context.helmet = server_default({ | ||
baseTag: [], | ||
bodyAttributes: {}, | ||
encodeSpecialCharacters: true, | ||
htmlAttributes: {}, | ||
linkTags: [], | ||
metaTags: [], | ||
noscriptTags: [], | ||
scriptTags: [], | ||
styleTags: [], | ||
title: "", | ||
titleAttributes: {} | ||
}); | ||
} | ||
} | ||
}; | ||
// src/Provider.tsx | ||
var defaultValue = {}; | ||
var Context = import_react2.default.createContext(defaultValue); | ||
var canUseDOM = typeof document !== "undefined"; | ||
var HelmetProvider = class _HelmetProvider extends import_react2.Component { | ||
static canUseDOM = canUseDOM; | ||
helmetData; | ||
constructor(props) { | ||
super(props); | ||
this.helmetData = new HelmetData(this.props.context || {}, _HelmetProvider.canUseDOM); | ||
constructor(context, canUseDOM2) { | ||
this.context = context; | ||
this.canUseDOM = canUseDOM2 || false; | ||
if (!canUseDOM2) { | ||
context.helmet = server_default({ | ||
baseTag: [], | ||
bodyAttributes: {}, | ||
encodeSpecialCharacters: true, | ||
htmlAttributes: {}, | ||
linkTags: [], | ||
metaTags: [], | ||
noscriptTags: [], | ||
scriptTags: [], | ||
styleTags: [], | ||
title: "", | ||
titleAttributes: {} | ||
}); | ||
} | ||
render() { | ||
return /* @__PURE__ */ import_react2.default.createElement(Context.Provider, { value: this.helmetData.value }, this.props.children); | ||
} | ||
}; | ||
} | ||
}; | ||
// src/Dispatcher.tsx | ||
var import_react3 = __require("react"); | ||
var import_shallowequal = __toESM(__require("shallowequal")); | ||
// src/Provider.tsx | ||
var defaultValue = {}; | ||
var Context = import_react2.default.createContext(defaultValue); | ||
var canUseDOM = typeof document !== "undefined"; | ||
var HelmetProvider = class _HelmetProvider extends import_react2.Component { | ||
static canUseDOM = canUseDOM; | ||
helmetData; | ||
constructor(props) { | ||
super(props); | ||
this.helmetData = new HelmetData(this.props.context || {}, _HelmetProvider.canUseDOM); | ||
} | ||
render() { | ||
return /* @__PURE__ */ import_react2.default.createElement(Context.Provider, { value: this.helmetData.value }, this.props.children); | ||
} | ||
}; | ||
// src/client.ts | ||
var updateTags = (type, tags) => { | ||
const headElement = document.head || document.querySelector("head" /* HEAD */); | ||
const tagNodes = headElement.querySelectorAll(`${type}[${HELMET_ATTRIBUTE}]`); | ||
const oldTags = [].slice.call(tagNodes); | ||
const newTags = []; | ||
let indexToDelete; | ||
if (tags && tags.length) { | ||
tags.forEach((tag) => { | ||
const newElement = document.createElement(type); | ||
for (const attribute in tag) { | ||
if (Object.prototype.hasOwnProperty.call(tag, attribute)) { | ||
if (attribute === "innerHTML" /* INNER_HTML */) { | ||
newElement.innerHTML = tag.innerHTML; | ||
} else if (attribute === "cssText" /* CSS_TEXT */) { | ||
if (newElement.styleSheet) { | ||
newElement.styleSheet.cssText = tag.cssText; | ||
} else { | ||
newElement.appendChild(document.createTextNode(tag.cssText)); | ||
} | ||
// src/Dispatcher.tsx | ||
var import_react3 = require("react"); | ||
var import_shallowequal = __toESM(require("shallowequal")); | ||
// src/client.ts | ||
var updateTags = (type, tags) => { | ||
const headElement = document.head || document.querySelector("head" /* HEAD */); | ||
const tagNodes = headElement.querySelectorAll(`${type}[${HELMET_ATTRIBUTE}]`); | ||
const oldTags = [].slice.call(tagNodes); | ||
const newTags = []; | ||
let indexToDelete; | ||
if (tags && tags.length) { | ||
tags.forEach((tag) => { | ||
const newElement = document.createElement(type); | ||
for (const attribute in tag) { | ||
if (Object.prototype.hasOwnProperty.call(tag, attribute)) { | ||
if (attribute === "innerHTML" /* INNER_HTML */) { | ||
newElement.innerHTML = tag.innerHTML; | ||
} else if (attribute === "cssText" /* CSS_TEXT */) { | ||
if (newElement.styleSheet) { | ||
newElement.styleSheet.cssText = tag.cssText; | ||
} else { | ||
const attr = attribute; | ||
const value = typeof tag[attr] === "undefined" ? "" : tag[attr]; | ||
newElement.setAttribute(attribute, value); | ||
newElement.appendChild(document.createTextNode(tag.cssText)); | ||
} | ||
} else { | ||
const attr = attribute; | ||
const value = typeof tag[attr] === "undefined" ? "" : tag[attr]; | ||
newElement.setAttribute(attribute, value); | ||
} | ||
} | ||
newElement.setAttribute(HELMET_ATTRIBUTE, "true"); | ||
if (oldTags.some((existingTag, index) => { | ||
indexToDelete = index; | ||
return newElement.isEqualNode(existingTag); | ||
})) { | ||
oldTags.splice(indexToDelete, 1); | ||
} else { | ||
newTags.push(newElement); | ||
} | ||
}); | ||
} | ||
oldTags.forEach((tag) => tag.parentNode?.removeChild(tag)); | ||
newTags.forEach((tag) => headElement.appendChild(tag)); | ||
return { | ||
oldTags, | ||
newTags | ||
}; | ||
}; | ||
var updateAttributes = (tagName, attributes) => { | ||
const elementTag = document.getElementsByTagName(tagName)[0]; | ||
if (!elementTag) { | ||
return; | ||
} | ||
const helmetAttributeString = elementTag.getAttribute(HELMET_ATTRIBUTE); | ||
const helmetAttributes = helmetAttributeString ? helmetAttributeString.split(",") : []; | ||
const attributesToRemove = [...helmetAttributes]; | ||
const attributeKeys = Object.keys(attributes); | ||
for (const attribute of attributeKeys) { | ||
const value = attributes[attribute] || ""; | ||
if (elementTag.getAttribute(attribute) !== value) { | ||
elementTag.setAttribute(attribute, value); | ||
} | ||
if (helmetAttributes.indexOf(attribute) === -1) { | ||
helmetAttributes.push(attribute); | ||
newElement.setAttribute(HELMET_ATTRIBUTE, "true"); | ||
if (oldTags.some((existingTag, index) => { | ||
indexToDelete = index; | ||
return newElement.isEqualNode(existingTag); | ||
})) { | ||
oldTags.splice(indexToDelete, 1); | ||
} else { | ||
newTags.push(newElement); | ||
} | ||
const indexToSave = attributesToRemove.indexOf(attribute); | ||
if (indexToSave !== -1) { | ||
attributesToRemove.splice(indexToSave, 1); | ||
} | ||
}); | ||
} | ||
oldTags.forEach((tag) => tag.parentNode?.removeChild(tag)); | ||
newTags.forEach((tag) => headElement.appendChild(tag)); | ||
return { | ||
oldTags, | ||
newTags | ||
}; | ||
}; | ||
var updateAttributes = (tagName, attributes) => { | ||
const elementTag = document.getElementsByTagName(tagName)[0]; | ||
if (!elementTag) { | ||
return; | ||
} | ||
const helmetAttributeString = elementTag.getAttribute(HELMET_ATTRIBUTE); | ||
const helmetAttributes = helmetAttributeString ? helmetAttributeString.split(",") : []; | ||
const attributesToRemove = [...helmetAttributes]; | ||
const attributeKeys = Object.keys(attributes); | ||
for (const attribute of attributeKeys) { | ||
const value = attributes[attribute] || ""; | ||
if (elementTag.getAttribute(attribute) !== value) { | ||
elementTag.setAttribute(attribute, value); | ||
} | ||
for (let i = attributesToRemove.length - 1; i >= 0; i -= 1) { | ||
elementTag.removeAttribute(attributesToRemove[i]); | ||
if (helmetAttributes.indexOf(attribute) === -1) { | ||
helmetAttributes.push(attribute); | ||
} | ||
if (helmetAttributes.length === attributesToRemove.length) { | ||
elementTag.removeAttribute(HELMET_ATTRIBUTE); | ||
} else if (elementTag.getAttribute(HELMET_ATTRIBUTE) !== attributeKeys.join(",")) { | ||
elementTag.setAttribute(HELMET_ATTRIBUTE, attributeKeys.join(",")); | ||
const indexToSave = attributesToRemove.indexOf(attribute); | ||
if (indexToSave !== -1) { | ||
attributesToRemove.splice(indexToSave, 1); | ||
} | ||
} | ||
for (let i = attributesToRemove.length - 1; i >= 0; i -= 1) { | ||
elementTag.removeAttribute(attributesToRemove[i]); | ||
} | ||
if (helmetAttributes.length === attributesToRemove.length) { | ||
elementTag.removeAttribute(HELMET_ATTRIBUTE); | ||
} else if (elementTag.getAttribute(HELMET_ATTRIBUTE) !== attributeKeys.join(",")) { | ||
elementTag.setAttribute(HELMET_ATTRIBUTE, attributeKeys.join(",")); | ||
} | ||
}; | ||
var updateTitle = (title, attributes) => { | ||
if (typeof title !== "undefined" && document.title !== title) { | ||
document.title = flattenArray(title); | ||
} | ||
updateAttributes("title" /* TITLE */, attributes); | ||
}; | ||
var commitTagChanges = (newState, cb) => { | ||
const { | ||
baseTag, | ||
bodyAttributes, | ||
htmlAttributes, | ||
linkTags, | ||
metaTags, | ||
noscriptTags, | ||
onChangeClientState, | ||
scriptTags, | ||
styleTags, | ||
title, | ||
titleAttributes | ||
} = newState; | ||
updateAttributes("body" /* BODY */, bodyAttributes); | ||
updateAttributes("html" /* HTML */, htmlAttributes); | ||
updateTitle(title, titleAttributes); | ||
const tagUpdates = { | ||
baseTag: updateTags("base" /* BASE */, baseTag), | ||
linkTags: updateTags("link" /* LINK */, linkTags), | ||
metaTags: updateTags("meta" /* META */, metaTags), | ||
noscriptTags: updateTags("noscript" /* NOSCRIPT */, noscriptTags), | ||
scriptTags: updateTags("script" /* SCRIPT */, scriptTags), | ||
styleTags: updateTags("style" /* STYLE */, styleTags) | ||
}; | ||
var updateTitle = (title, attributes) => { | ||
if (typeof title !== "undefined" && document.title !== title) { | ||
document.title = flattenArray(title); | ||
const addedTags = {}; | ||
const removedTags = {}; | ||
Object.keys(tagUpdates).forEach((tagType) => { | ||
const { newTags, oldTags } = tagUpdates[tagType]; | ||
if (newTags.length) { | ||
addedTags[tagType] = newTags; | ||
} | ||
updateAttributes("title" /* TITLE */, attributes); | ||
}; | ||
var commitTagChanges = (newState, cb) => { | ||
const { | ||
baseTag, | ||
bodyAttributes, | ||
htmlAttributes, | ||
linkTags, | ||
metaTags, | ||
noscriptTags, | ||
onChangeClientState, | ||
scriptTags, | ||
styleTags, | ||
title, | ||
titleAttributes | ||
} = newState; | ||
updateAttributes("body" /* BODY */, bodyAttributes); | ||
updateAttributes("html" /* HTML */, htmlAttributes); | ||
updateTitle(title, titleAttributes); | ||
const tagUpdates = { | ||
baseTag: updateTags("base" /* BASE */, baseTag), | ||
linkTags: updateTags("link" /* LINK */, linkTags), | ||
metaTags: updateTags("meta" /* META */, metaTags), | ||
noscriptTags: updateTags("noscript" /* NOSCRIPT */, noscriptTags), | ||
scriptTags: updateTags("script" /* SCRIPT */, scriptTags), | ||
styleTags: updateTags("style" /* STYLE */, styleTags) | ||
}; | ||
const addedTags = {}; | ||
const removedTags = {}; | ||
Object.keys(tagUpdates).forEach((tagType) => { | ||
const { newTags, oldTags } = tagUpdates[tagType]; | ||
if (newTags.length) { | ||
addedTags[tagType] = newTags; | ||
} | ||
if (oldTags.length) { | ||
removedTags[tagType] = tagUpdates[tagType].oldTags; | ||
} | ||
}); | ||
if (cb) { | ||
cb(); | ||
if (oldTags.length) { | ||
removedTags[tagType] = tagUpdates[tagType].oldTags; | ||
} | ||
onChangeClientState(newState, addedTags, removedTags); | ||
}; | ||
var _helmetCallback = null; | ||
var handleStateChangeOnClient = (newState) => { | ||
if (_helmetCallback) { | ||
cancelAnimationFrame(_helmetCallback); | ||
} | ||
if (newState.defer) { | ||
_helmetCallback = requestAnimationFrame(() => { | ||
commitTagChanges(newState, () => { | ||
_helmetCallback = null; | ||
}); | ||
}); | ||
if (cb) { | ||
cb(); | ||
} | ||
onChangeClientState(newState, addedTags, removedTags); | ||
}; | ||
var _helmetCallback = null; | ||
var handleStateChangeOnClient = (newState) => { | ||
if (_helmetCallback) { | ||
cancelAnimationFrame(_helmetCallback); | ||
} | ||
if (newState.defer) { | ||
_helmetCallback = requestAnimationFrame(() => { | ||
commitTagChanges(newState, () => { | ||
_helmetCallback = null; | ||
}); | ||
} else { | ||
commitTagChanges(newState); | ||
_helmetCallback = null; | ||
} | ||
}; | ||
var client_default = handleStateChangeOnClient; | ||
}); | ||
} else { | ||
commitTagChanges(newState); | ||
_helmetCallback = null; | ||
} | ||
}; | ||
var client_default = handleStateChangeOnClient; | ||
// src/Dispatcher.tsx | ||
var HelmetDispatcher = class extends import_react3.Component { | ||
rendered = false; | ||
shouldComponentUpdate(nextProps) { | ||
return !(0, import_shallowequal.default)(nextProps, this.props); | ||
// src/Dispatcher.tsx | ||
var HelmetDispatcher = class extends import_react3.Component { | ||
rendered = false; | ||
shouldComponentUpdate(nextProps) { | ||
return !(0, import_shallowequal.default)(nextProps, this.props); | ||
} | ||
componentDidUpdate() { | ||
this.emitChange(); | ||
} | ||
componentWillUnmount() { | ||
const { helmetInstances } = this.props.context; | ||
helmetInstances.remove(this); | ||
this.emitChange(); | ||
} | ||
emitChange() { | ||
const { helmetInstances, setHelmet } = this.props.context; | ||
let serverState = null; | ||
const state = reducePropsToState( | ||
helmetInstances.get().map((instance) => { | ||
const props = { ...instance.props }; | ||
delete props.context; | ||
return props; | ||
}) | ||
); | ||
if (HelmetProvider.canUseDOM) { | ||
client_default(state); | ||
} else if (server_default) { | ||
serverState = server_default(state); | ||
} | ||
componentDidUpdate() { | ||
this.emitChange(); | ||
setHelmet(serverState); | ||
} | ||
// componentWillMount will be deprecated | ||
// for SSR, initialize on first render | ||
// constructor is also unsafe in StrictMode | ||
init() { | ||
if (this.rendered) { | ||
return; | ||
} | ||
componentWillUnmount() { | ||
const { helmetInstances } = this.props.context; | ||
helmetInstances.remove(this); | ||
this.emitChange(); | ||
this.rendered = true; | ||
const { helmetInstances } = this.props.context; | ||
helmetInstances.add(this); | ||
this.emitChange(); | ||
} | ||
render() { | ||
this.init(); | ||
return null; | ||
} | ||
}; | ||
// src/index.tsx | ||
var Helmet = class extends import_react4.Component { | ||
static defaultProps = { | ||
defer: true, | ||
encodeSpecialCharacters: true, | ||
prioritizeSeoTags: false | ||
}; | ||
shouldComponentUpdate(nextProps) { | ||
return !(0, import_react_fast_compare.default)(without(this.props, "helmetData"), without(nextProps, "helmetData")); | ||
} | ||
mapNestedChildrenToProps(child, nestedChildren) { | ||
if (!nestedChildren) { | ||
return null; | ||
} | ||
emitChange() { | ||
const { helmetInstances, setHelmet } = this.props.context; | ||
let serverState = null; | ||
const state = reducePropsToState( | ||
helmetInstances.get().map((instance) => { | ||
const props = { ...instance.props }; | ||
delete props.context; | ||
return props; | ||
}) | ||
); | ||
if (HelmetProvider.canUseDOM) { | ||
client_default(state); | ||
} else if (server_default) { | ||
serverState = server_default(state); | ||
} | ||
setHelmet(serverState); | ||
switch (child.type) { | ||
case "script" /* SCRIPT */: | ||
case "noscript" /* NOSCRIPT */: | ||
return { | ||
innerHTML: nestedChildren | ||
}; | ||
case "style" /* STYLE */: | ||
return { | ||
cssText: nestedChildren | ||
}; | ||
default: | ||
throw new Error( | ||
`<${child.type} /> elements are self-closing and can not contain children. Refer to our API for more information.` | ||
); | ||
} | ||
// componentWillMount will be deprecated | ||
// for SSR, initialize on first render | ||
// constructor is also unsafe in StrictMode | ||
init() { | ||
if (this.rendered) { | ||
return; | ||
} | ||
this.rendered = true; | ||
const { helmetInstances } = this.props.context; | ||
helmetInstances.add(this); | ||
this.emitChange(); | ||
} | ||
render() { | ||
this.init(); | ||
return null; | ||
} | ||
}; | ||
// src/index.tsx | ||
var Helmet = class extends import_react4.Component { | ||
static defaultProps = { | ||
defer: true, | ||
encodeSpecialCharacters: true, | ||
prioritizeSeoTags: false | ||
} | ||
flattenArrayTypeChildren(child, arrayTypeChildren, newChildProps, nestedChildren) { | ||
return { | ||
...arrayTypeChildren, | ||
[child.type]: [ | ||
...arrayTypeChildren[child.type] || [], | ||
{ | ||
...newChildProps, | ||
...this.mapNestedChildrenToProps(child, nestedChildren) | ||
} | ||
] | ||
}; | ||
shouldComponentUpdate(nextProps) { | ||
return !(0, import_react_fast_compare.default)(without(this.props, "helmetData"), without(nextProps, "helmetData")); | ||
} | ||
mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren) { | ||
switch (child.type) { | ||
case "title" /* TITLE */: | ||
return { | ||
...newProps, | ||
[child.type]: nestedChildren, | ||
titleAttributes: { ...newChildProps } | ||
}; | ||
case "body" /* BODY */: | ||
return { | ||
...newProps, | ||
bodyAttributes: { ...newChildProps } | ||
}; | ||
case "html" /* HTML */: | ||
return { | ||
...newProps, | ||
htmlAttributes: { ...newChildProps } | ||
}; | ||
default: | ||
return { | ||
...newProps, | ||
[child.type]: { ...newChildProps } | ||
}; | ||
} | ||
mapNestedChildrenToProps(child, nestedChildren) { | ||
if (!nestedChildren) { | ||
return null; | ||
} | ||
mapArrayTypeChildrenToProps(arrayTypeChildren, newProps) { | ||
let newFlattenedProps = { ...newProps }; | ||
Object.keys(arrayTypeChildren).forEach((arrayChildName) => { | ||
newFlattenedProps = { | ||
...newFlattenedProps, | ||
[arrayChildName]: arrayTypeChildren[arrayChildName] | ||
}; | ||
}); | ||
return newFlattenedProps; | ||
} | ||
warnOnInvalidChildren(child, nestedChildren) { | ||
(0, import_invariant.default)( | ||
VALID_TAG_NAMES.some((name) => child.type === name), | ||
typeof child.type === "function" ? `You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.` : `Only elements types ${VALID_TAG_NAMES.join( | ||
", " | ||
)} are allowed. Helmet does not support rendering <${child.type}> elements. Refer to our API for more information.` | ||
); | ||
(0, import_invariant.default)( | ||
!nestedChildren || typeof nestedChildren === "string" || Array.isArray(nestedChildren) && !nestedChildren.some((nestedChild) => typeof nestedChild !== "string"), | ||
`Helmet expects a string as a child of <${child.type}>. Did you forget to wrap your children in braces? ( <${child.type}>{\`\`}</${child.type}> ) Refer to our API for more information.` | ||
); | ||
return true; | ||
} | ||
mapChildrenToProps(children, newProps) { | ||
let arrayTypeChildren = {}; | ||
import_react4.default.Children.forEach(children, (child) => { | ||
if (!child || !child.props) { | ||
return; | ||
} | ||
switch (child.type) { | ||
const { children: nestedChildren, ...childProps } = child.props; | ||
const newChildProps = Object.keys(childProps).reduce((obj, key) => { | ||
obj[HTML_TAG_MAP[key] || key] = childProps[key]; | ||
return obj; | ||
}, {}); | ||
let { type } = child; | ||
if (typeof type === "symbol") { | ||
type = type.toString(); | ||
} else { | ||
this.warnOnInvalidChildren(child, nestedChildren); | ||
} | ||
switch (type) { | ||
case "Symbol(react.fragment)" /* FRAGMENT */: | ||
newProps = this.mapChildrenToProps(nestedChildren, newProps); | ||
break; | ||
case "link" /* LINK */: | ||
case "meta" /* META */: | ||
case "noscript" /* NOSCRIPT */: | ||
case "script" /* SCRIPT */: | ||
case "noscript" /* NOSCRIPT */: | ||
return { | ||
innerHTML: nestedChildren | ||
}; | ||
case "style" /* STYLE */: | ||
return { | ||
cssText: nestedChildren | ||
}; | ||
default: | ||
throw new Error( | ||
`<${child.type} /> elements are self-closing and can not contain children. Refer to our API for more information.` | ||
arrayTypeChildren = this.flattenArrayTypeChildren( | ||
child, | ||
arrayTypeChildren, | ||
newChildProps, | ||
nestedChildren | ||
); | ||
} | ||
} | ||
flattenArrayTypeChildren(child, arrayTypeChildren, newChildProps, nestedChildren) { | ||
return { | ||
...arrayTypeChildren, | ||
[child.type]: [ | ||
...arrayTypeChildren[child.type] || [], | ||
{ | ||
...newChildProps, | ||
...this.mapNestedChildrenToProps(child, nestedChildren) | ||
} | ||
] | ||
}; | ||
} | ||
mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren) { | ||
switch (child.type) { | ||
case "title" /* TITLE */: | ||
return { | ||
...newProps, | ||
[child.type]: nestedChildren, | ||
titleAttributes: { ...newChildProps } | ||
}; | ||
case "body" /* BODY */: | ||
return { | ||
...newProps, | ||
bodyAttributes: { ...newChildProps } | ||
}; | ||
case "html" /* HTML */: | ||
return { | ||
...newProps, | ||
htmlAttributes: { ...newChildProps } | ||
}; | ||
break; | ||
default: | ||
return { | ||
...newProps, | ||
[child.type]: { ...newChildProps } | ||
}; | ||
newProps = this.mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren); | ||
break; | ||
} | ||
}); | ||
return this.mapArrayTypeChildrenToProps(arrayTypeChildren, newProps); | ||
} | ||
render() { | ||
const { children, ...props } = this.props; | ||
let newProps = { ...props }; | ||
let { helmetData } = props; | ||
if (children) { | ||
newProps = this.mapChildrenToProps(children, newProps); | ||
} | ||
mapArrayTypeChildrenToProps(arrayTypeChildren, newProps) { | ||
let newFlattenedProps = { ...newProps }; | ||
Object.keys(arrayTypeChildren).forEach((arrayChildName) => { | ||
newFlattenedProps = { | ||
...newFlattenedProps, | ||
[arrayChildName]: arrayTypeChildren[arrayChildName] | ||
}; | ||
}); | ||
return newFlattenedProps; | ||
if (helmetData && !(helmetData instanceof HelmetData)) { | ||
const data = helmetData; | ||
helmetData = new HelmetData(data.context, true); | ||
delete newProps.helmetData; | ||
} | ||
warnOnInvalidChildren(child, nestedChildren) { | ||
(0, import_invariant.default)( | ||
VALID_TAG_NAMES.some((name) => child.type === name), | ||
typeof child.type === "function" ? `You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.` : `Only elements types ${VALID_TAG_NAMES.join( | ||
", " | ||
)} are allowed. Helmet does not support rendering <${child.type}> elements. Refer to our API for more information.` | ||
); | ||
(0, import_invariant.default)( | ||
!nestedChildren || typeof nestedChildren === "string" || Array.isArray(nestedChildren) && !nestedChildren.some((nestedChild) => typeof nestedChild !== "string"), | ||
`Helmet expects a string as a child of <${child.type}>. Did you forget to wrap your children in braces? ( <${child.type}>{\`\`}</${child.type}> ) Refer to our API for more information.` | ||
); | ||
return true; | ||
} | ||
mapChildrenToProps(children, newProps) { | ||
let arrayTypeChildren = {}; | ||
import_react4.default.Children.forEach(children, (child) => { | ||
if (!child || !child.props) { | ||
return; | ||
} | ||
const { children: nestedChildren, ...childProps } = child.props; | ||
const newChildProps = Object.keys(childProps).reduce((obj, key) => { | ||
obj[HTML_TAG_MAP[key] || key] = childProps[key]; | ||
return obj; | ||
}, {}); | ||
let { type } = child; | ||
if (typeof type === "symbol") { | ||
type = type.toString(); | ||
} else { | ||
this.warnOnInvalidChildren(child, nestedChildren); | ||
} | ||
switch (type) { | ||
case "Symbol(react.fragment)" /* FRAGMENT */: | ||
newProps = this.mapChildrenToProps(nestedChildren, newProps); | ||
break; | ||
case "link" /* LINK */: | ||
case "meta" /* META */: | ||
case "noscript" /* NOSCRIPT */: | ||
case "script" /* SCRIPT */: | ||
case "style" /* STYLE */: | ||
arrayTypeChildren = this.flattenArrayTypeChildren( | ||
child, | ||
arrayTypeChildren, | ||
newChildProps, | ||
nestedChildren | ||
); | ||
break; | ||
default: | ||
newProps = this.mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren); | ||
break; | ||
} | ||
}); | ||
return this.mapArrayTypeChildrenToProps(arrayTypeChildren, newProps); | ||
} | ||
render() { | ||
const { children, ...props } = this.props; | ||
let newProps = { ...props }; | ||
let { helmetData } = props; | ||
if (children) { | ||
newProps = this.mapChildrenToProps(children, newProps); | ||
} | ||
if (helmetData && !(helmetData instanceof HelmetData)) { | ||
const data = helmetData; | ||
helmetData = new HelmetData(data.context, true); | ||
delete newProps.helmetData; | ||
} | ||
return helmetData ? /* @__PURE__ */ import_react4.default.createElement(HelmetDispatcher, { ...newProps, context: helmetData.value }) : /* @__PURE__ */ import_react4.default.createElement(Context.Consumer, null, (context) => /* @__PURE__ */ import_react4.default.createElement(HelmetDispatcher, { ...newProps, context })); | ||
} | ||
}; | ||
})(); | ||
return helmetData ? /* @__PURE__ */ import_react4.default.createElement(HelmetDispatcher, { ...newProps, context: helmetData.value }) : /* @__PURE__ */ import_react4.default.createElement(Context.Consumer, null, (context) => /* @__PURE__ */ import_react4.default.createElement(HelmetDispatcher, { ...newProps, context })); | ||
} | ||
}; |
{ | ||
"name": "react-helmet-async", | ||
"version": "2.0.0-alpha", | ||
"version": "2.0.1-alpha", | ||
"description": "Thread-safe Helmet for React 16+ and friends", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
1931
1
0
86249