openaire-library/sharedComponents/SEO/SEO.service.ts

137 lines
4.4 KiB
TypeScript

import { Injectable, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Optional, RendererFactory2, ViewEncapsulation } from '@angular/core';
@Injectable()
export class SEOService {
constructor( @Inject(DOCUMENT) private doc,
private rendererFactory: RendererFactory2,
@Inject(DOCUMENT) private document) {
}
createLinkForCanonicalURL(url:string, addParameters:boolean=true) {
if(this.doc && (typeof this.doc.getElementById === "function" || typeof this.doc.createElement === "function") ){
if(addParameters || !this.doc.URL || this.doc.URL.indexOf("?") == -1){
url = this.doc.URL;
}else{
url = this.doc.URL.substring(0,this.doc.URL.indexOf("?"));
}
if (typeof this.doc.getElementById === "function") {
let currentLink: HTMLLinkElement = this.doc.getElementById("relcan");
if(currentLink ){
currentLink.setAttribute('href', url);
return ;
}
}
if (typeof this.doc.createElement === "function") {
let link: HTMLLinkElement = this.doc.createElement('link');
link.setAttribute('id', 'relcan');
link.setAttribute('rel', 'canonical');
this.doc.head.appendChild(link);
link.setAttribute('href', url);
}
}else{
try {
const renderer = this.rendererFactory.createRenderer(this.document, {
id: '-1',
encapsulation: ViewEncapsulation.None,
styles: [],
data: {}
});
const link = renderer.createElement('link');
const head = this.document.head;
if (head === null) {
throw new Error('<head> not found within DOCUMENT.');
}
renderer.setAttribute(link, "rel", "canonical");
renderer.setAttribute(link, "href", (addParameters)?url:url.split("?")[0]);
renderer.setAttribute(link, "id", "relcan");
// [TODO]: get them to update the existing one (if it exists) ?
renderer.appendChild(head, link);
} catch (e) {
console.error('Error within linkService : ', e);
}
}
}
}
/*
* -- LinkService -- [Temporary]
* @MarkPieszak
*
* Similar to Meta service but made to handle <link> creation for SEO purposes
* -- NOTE: Soon there will be an overall DocumentService within Angular that handles Meta/Link everything
*/
//
// import { Injectable, Optional, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core';
// import { DOCUMENT } from '@angular/platform-browser';
//
// @Injectable()
// export class LinkService {
//
// constructor(
// private rendererFactory: RendererFactory2,
// @Inject(DOCUMENT) private document
// ) {
// }
/**
* Inject the State into the bottom of the <head>
*/
// addTag(tag: LinkDefinition, forceCreation?: boolean) {
//
// try {
// const renderer = this.rendererFactory.createRenderer(this.document, {
// id: '-1',
// encapsulation: ViewEncapsulation.None,
// styles: [],
// data: {}
// });
//
// const link = renderer.createElement('link');
// const head = this.document.head;
// const selector = this._parseSelector(tag);
//
// if (head === null) {
// throw new Error('<head> not found within DOCUMENT.');
// }
//
// Object.keys(tag).forEach((prop: string) => {
// return renderer.setAttribute(link, prop, tag[prop]);
// });
//
// // [TODO]: get them to update the existing one (if it exists) ?
// renderer.appendChild(head, link);
//
// } catch (e) {
// console.error('Error within linkService : ', e);
// }
// }
//
// private _parseSelector(tag: LinkDefinition): string {
// // Possibly re-work this
// const attr: string = tag.rel ? 'rel' : 'hreflang';
// return `${attr}="${tag[attr]}"`;
// }
// }
export declare type LinkDefinition = {
charset?: string;
crossorigin?: string;
href?: string;
hreflang?: string;
media?: string;
rel?: string;
rev?: string;
sizes?: string;
target?: string;
type?: string;
} & {
[prop: string]: string;
};