{"version":3,"file":"meta-tags-nodftgie.js","sources":["packages/vanilla/lib/features/meta-tags/src/meta-tags.client-config.ts","packages/vanilla/lib/features/meta-tags/src/meta-tags.service.ts","packages/vanilla/lib/features/meta-tags/src/meta-tags-bootstrap.service.ts","packages/vanilla/lib/features/meta-tags/src/meta-tags.feature.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\nimport { ClientConfigProductName, LazyClientConfig, LazyClientConfigBase, LazyClientConfigService } from '@frontend/vanilla/core';\n\nexport type TagCollection = { [name: string]: string | null };\n\nexport interface PageMetaTagsRule {\n    urlPath: string;\n    urlQueryParams: { [name: string]: string };\n    title: string | null;\n    tags: TagCollection;\n}\n\nexport interface GlobalMetaTagsRule {\n    tags: TagCollection;\n    urlPathAndQueryRegexes: string[];\n    ruleName: string;\n}\n\n@LazyClientConfig({ key: 'vnMetaTags', product: ClientConfigProductName.SF })\n@Injectable({\n    providedIn: 'root',\n    deps: [LazyClientConfigService],\n    useFactory: metaTagsConfigFactory,\n})\nexport class MetaTagsConfig extends LazyClientConfigBase {\n    pageMetaTags: PageMetaTagsRule[];\n    globalMetaTags: GlobalMetaTagsRule[];\n}\n\nexport function metaTagsConfigFactory(service: LazyClientConfigService) {\n    return service.get(MetaTagsConfig);\n}\n","import { Injectable } from '@angular/core';\n\nimport { CaseInsensitiveMap, Logger, NavigationService, PageService, RevertiblePageChange } from '@frontend/vanilla/core';\nimport { transform } from 'lodash-es';\n\nimport { MetaTagsConfig, PageMetaTagsRule, TagCollection } from './meta-tags.client-config';\n\nconst TITLE_CHANGE_KEY = '_vanilla:pageTitle_';\n\n/**\n * @whatItDoes Manipulates page metadata (like title and meta tags).\n *\n * @howToUse\n *\n * ```\n * ngOnInit() {\n *     this.metaTagsService.setPageTags('Page Title', {\n *         description: 'This is awesome page.',\n *         author: 'Chuck Norris'\n *     }\n * }\n * ```\n *\n * @description\n *\n * You can use this service to change (or add) title and meta tags. All changes will survive only for particular page (until next navigation).\n * Values are automatically merged with configured ones by SEO analysts which take precedence.\n *\n * Values are automatically set for public pages displayed via {@link PageMatrixComponent}.\n *\n * @stable\n */\n@Injectable({\n    providedIn: 'root',\n})\nexport class MetaTagsService {\n    private pageMetaTags: PageMetaTagsRule[];\n    private globalMetaTags: GlobalMetaTagsRule[];\n    private globalChanges: Map<string, RevertiblePageChange> = new CaseInsensitiveMap();\n    private customChanges: Map<string, RevertiblePageChange> = new CaseInsensitiveMap();\n\n    constructor(\n        private pageService: PageService,\n        private config: MetaTagsConfig,\n        private navigationService: NavigationService,\n        private log: Logger,\n    ) {}\n\n    /**\n     * @internal\n     */\n    initialize(): void {\n        // prepare tags - create regexes, normalize urls\n        this.pageMetaTags = this.config.pageMetaTags.map<PageMetaTagsRule>((r) => ({\n            urlPath: normalizeUrlValue(r.urlPath),\n            urlQueryParams: transform(\n                r.urlQueryParams,\n                (obj: Record<string, string>, val, name) => (obj[normalizeUrlValue(name)] = normalizeUrlValue(val)),\n                {},\n            ),\n            title: r.title,\n            tags: r.tags,\n        }));\n        this.globalMetaTags = this.config.globalMetaTags.map<GlobalMetaTagsRule>((r) => ({\n            tags: r.tags,\n            urlPathAndQueryRegexes: r.urlPathAndQueryRegexes.map((x) => {\n                try {\n                    return new RegExp(x, 'i');\n                } catch (e) {\n                    this.log.errorRemote(\n                        `Failed to compile regex /${x}/ because it's not supported on this browser. So it won't be executed for SEO global meta tag rule \"${r.ruleName}\".`,\n                        e,\n                    );\n                    return new RegExp('.^');\n                }\n            }),\n        }));\n\n        // register evaluation\n        this.navigationService.locationChange.subscribe(() => this.evaluateSeoTags());\n        this.evaluateSeoTags();\n    }\n\n    /**\n     * Sets title and meta tags for current page (until next navigation).\n     */\n    setPageTags(title?: string, tags?: { [name: string]: string }): void {\n        this.applyTitle(title, this.customChanges);\n        this.applyTags(tags || {}, this.customChanges);\n    }\n\n    /**\n     * Clears values previously set by `setMetaTags`. This is usually done automatically on location change, but\n     */\n    clearPageTags() {\n        this.clearCustomChanges();\n    }\n\n    private evaluateSeoTags(): void {\n        // revert changes from previous page\n        this.clearCustomChanges();\n        this.clearGlobalChanges();\n\n        // find rule matching current page\n        const path = normalizeUrlValue(this.navigationService.location.path());\n        const query = this.navigationService.location.search;\n        const qs = query.toString();\n        const pathAndQuery = decodeURI(path + (qs ? '?' + qs : ''));\n\n        const pageRule = this.pageMetaTags.find(\n            (r) =>\n                r.urlPath === path &&\n                Object.keys(r.urlQueryParams).every((name) => {\n                    const val = query.get(name);\n                    return val !== null && normalizeUrlValue(val) === r.urlQueryParams[name];\n                }),\n        );\n\n        // apply page rule\n        if (pageRule) {\n            this.applyTitle(pageRule.title, this.globalChanges);\n            this.applyTags(pageRule.tags, this.globalChanges);\n        }\n\n        // apply global rules\n        for (const globalRule of this.globalMetaTags) {\n            if (globalRule.urlPathAndQueryRegexes.some((r) => r.test(pathAndQuery))) {\n                this.applyTags(globalRule.tags, this.globalChanges);\n            }\n        }\n    }\n\n    private clearCustomChanges() {\n        this.customChanges.forEach((c) => c.revert());\n        this.customChanges.clear();\n    }\n\n    private clearGlobalChanges() {\n        this.globalChanges.forEach((c) => c.revert());\n        this.globalChanges.clear();\n    }\n\n    private applyTitle(title: string | null | undefined, changes: Map<string, RevertiblePageChange>) {\n        if (typeof title === 'string' && !this.changeExists(TITLE_CHANGE_KEY)) {\n            const change = this.pageService.setTitle(title);\n            changes.set(TITLE_CHANGE_KEY, change);\n        }\n    }\n\n    private applyTags(tags: TagCollection, changes: Map<string, RevertiblePageChange>): void {\n        for (const name of Object.keys(tags)) {\n            if (!name.trim().length) {\n                throw new Error(`Tag name cannot be null nor white-space but such one was specified with value \"${tags[name]}\".`);\n            }\n            if (!this.changeExists(name)) {\n                const change = this.pageService.setMeta(name, tags[name]!);\n                changes.set(name, change);\n            }\n        }\n    }\n\n    private changeExists(name: string) {\n        return this.globalChanges.has(name) || this.customChanges.has(name);\n    }\n}\n\nfunction normalizeUrlValue(str: string): string {\n    return str ? str.toLowerCase() : str;\n}\n\ninterface GlobalMetaTagsRule {\n    tags: TagCollection;\n    urlPathAndQueryRegexes: RegExp[]; // config diff: regexes instead of strings\n}\n","import { Injectable } from '@angular/core';\n\nimport { MetaTagsService as CoreMetaTagsService, OnFeatureInit } from '@frontend/vanilla/core';\nimport { firstValueFrom } from 'rxjs';\n\nimport { MetaTagsConfig } from './meta-tags.client-config';\nimport { MetaTagsService } from './meta-tags.service';\n\n@Injectable()\nexport class MetaTagsBootstrapService implements OnFeatureInit {\n    constructor(\n        private config: MetaTagsConfig,\n        private metaTagsService: MetaTagsService,\n        private coreMetaTagsService: CoreMetaTagsService,\n    ) {}\n\n    async onFeatureInit() {\n        await firstValueFrom(this.config.whenReady);\n        this.metaTagsService.initialize();\n        this.coreMetaTagsService.set(this.metaTagsService);\n    }\n}\n","import { runOnFeatureInit } from '@frontend/vanilla/core';\n\nimport { MetaTagsBootstrapService } from './meta-tags-bootstrap.service';\n\nexport function provide() {\n    return [runOnFeatureInit(MetaTagsBootstrapService)];\n}\n"],"names":["MetaTagsConfig","_a","LazyClientConfigBase","b","__ngFactoryType__","l","factory","__ngConditionalFactory__","metaTagsConfigFactory","ɵɵinject","LazyClientConfigService","__decorate","LazyClientConfig","key","product","ClientConfigProductName","SF","service","get","TITLE_CHANGE_KEY","MetaTagsService","constructor","pageService","config","navigationService","log","globalChanges","CaseInsensitiveMap","customChanges","initialize","pageMetaTags","map","r","urlPath","normalizeUrlValue","urlQueryParams","transform","obj","val","name","title","tags","globalMetaTags","urlPathAndQueryRegexes","x","RegExp","e","errorRemote","ruleName","locationChange","subscribe","evaluateSeoTags","setPageTags","applyTitle","applyTags","clearPageTags","clearCustomChanges","clearGlobalChanges","path","location","query","search","qs","toString","pathAndQuery","decodeURI","pageRule","find","Object","keys","every","globalRule","some","test","forEach","c","revert","clear","changes","changeExists","change","setTitle","set","trim","length","Error","setMeta","has","PageService","NavigationService","Logger","ɵfac","providedIn","_MetaTagsService","str","toLowerCase","MetaTagsBootstrapService","metaTagsService","coreMetaTagsService","onFeatureInit","__async","firstValueFrom","whenReady","_MetaTagsBootstrapService","provide","runOnFeatureInit"],"mappings":"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"}