@ima/core
Version:
IMA.js framework for isomorphic javascript application
85 lines (84 loc) • 3.07 kB
JavaScript
import { PageHandler } from './PageHandler';
import { MetaManager } from '../../meta/MetaManager';
import { Window } from '../../window/Window';
export const IMA_META_DATA_ATTR = 'data-ima-meta';
export class PageMetaHandler extends PageHandler {
#window;
#metaManager;
#managed = false;
static get $dependencies() {
return [
Window,
MetaManager
];
}
constructor(window, metaManager){
super();
this.#window = window;
this.#metaManager = metaManager;
}
/**
* @inheritDoc
*/ handlePreManagedState() {
this.#metaManager.clearMetaAttributes();
}
/**
* @inheritDoc
*/ handlePostManagedState() {
// Skip first manage state after SSR, so we don't
if (!this.#window.getWindow()?.$IMA?.SPA && !this.#managed && this.#selectMetaTags().length) {
this.#managed = true;
return;
}
this.#updateMetaAttributes();
}
/**
* Update specified meta or link tags in DOM.
*
* @param metaManager meta attributes storage providing the
* new values for page meta elements and title.
*/ #updateMetaAttributes() {
this.#window.setTitle(this.#metaManager.getTitle());
// Remove IMA managed meta tags
this.#selectMetaTags().forEach((el)=>el?.remove());
// Set title
this.#window.setTitle(this.#metaManager.getTitle());
// Update meta tags
this.#updateMetaTag(this.#metaManager.getLinksIterator(), 'link', 'rel');
this.#updateMetaTag(this.#metaManager.getMetaNamesIterator(), 'meta', 'name');
this.#updateMetaTag(this.#metaManager.getMetaPropertiesIterator(), 'meta', 'property');
}
/**
* Helper to update specific meta tags in page document.
*
* @param iterator Collection of meta records to update.
* @param tagName Tag name for the given collection.
* @param valueName Name of the main value for given meta collection.
*/ #updateMetaTag(iterator, tagName, keyName) {
const document = this.#window.getDocument();
for (const [key, value] of iterator){
const attributes = {
[keyName]: key,
...value
};
const metaTag = document.createElement(tagName);
metaTag.setAttribute(IMA_META_DATA_ATTR, '');
for (const [attrName, attrValue] of Object.entries(attributes)){
const sanitizedAttrValue = this.#sanitizeValue(attrValue);
// Skip empty values
if (sanitizedAttrValue === null) {
continue;
}
metaTag.setAttribute(attrName, sanitizedAttrValue);
}
document?.head?.appendChild(metaTag);
}
}
#sanitizeValue(value) {
return value === undefined || value === null ? null : value.toString();
}
#selectMetaTags() {
return this.#window.querySelectorAll(`[${IMA_META_DATA_ATTR}]`);
}
}
//# sourceMappingURL=PageMetaHandler.js.map