1
|
import { Injectable, Inject } from '@angular/core';
|
2
|
import { DOCUMENT } from '@angular/common';
|
3
|
import { Optional, RendererFactory2, ViewEncapsulation } from '@angular/core';
|
4
|
|
5
|
@Injectable()
|
6
|
export class SEOService {
|
7
|
constructor( @Inject(DOCUMENT) private doc,
|
8
|
private rendererFactory: RendererFactory2,
|
9
|
@Inject(DOCUMENT) private document) {
|
10
|
}
|
11
|
|
12
|
createLinkForCanonicalURL(url:string, addParameters:boolean=true) {
|
13
|
this.createLink(url,"relcan", "canonical", addParameters)
|
14
|
}
|
15
|
createLinkForCanonicalSearchURL(url:string, addParameters:boolean=true, ) {
|
16
|
this.createLink(url,"relcan", "canonical", addParameters);
|
17
|
this.createLink(url,"relnext", "next", addParameters)
|
18
|
this.createLink(url,"relprev", "prev", addParameters)
|
19
|
}
|
20
|
createLinkForNextURL(url:string, addParameters:boolean=true) {
|
21
|
this.createLink(url,"relnext", "next", addParameters)
|
22
|
}
|
23
|
createLinkForPrevURL(url:string, addParameters:boolean=true) {
|
24
|
this.createLink(url,"relprev", "prev", addParameters)
|
25
|
}
|
26
|
|
27
|
createLink(url:string, id:string, relname:string, addParameters:boolean=true) {
|
28
|
if(this.doc && (typeof this.doc.getElementById === "function" || typeof this.doc.createElement === "function") ){
|
29
|
if(!addParameters && url && url.indexOf("?") != -1){
|
30
|
url = url.substring(0,url.indexOf("?"));
|
31
|
}
|
32
|
if (typeof this.doc.getElementById === "function") {
|
33
|
let currentLink: HTMLLinkElement = this.doc.getElementById(id);
|
34
|
if(currentLink ){
|
35
|
currentLink.setAttribute('href', url);
|
36
|
return ;
|
37
|
}
|
38
|
}
|
39
|
if (typeof this.doc.createElement === "function") {
|
40
|
let link: HTMLLinkElement = this.doc.createElement('link');
|
41
|
link.setAttribute('id', id);
|
42
|
link.setAttribute('rel', relname);
|
43
|
this.doc.head.appendChild(link);
|
44
|
link.setAttribute('href', url);
|
45
|
}
|
46
|
|
47
|
}else{
|
48
|
try {
|
49
|
const renderer = this.rendererFactory.createRenderer(this.document, {
|
50
|
id: '-1',
|
51
|
encapsulation: ViewEncapsulation.None,
|
52
|
styles: [],
|
53
|
data: {}
|
54
|
});
|
55
|
|
56
|
const link = renderer.createElement('link');
|
57
|
const head = this.document.head;
|
58
|
|
59
|
if (head === null) {
|
60
|
throw new Error('<head> not found within DOCUMENT.');
|
61
|
}
|
62
|
renderer.setAttribute(link, "rel", relname);
|
63
|
renderer.setAttribute(link, "href", (addParameters)?url:url.split("?")[0]);
|
64
|
renderer.setAttribute(link, "id", id);
|
65
|
// [TODO]: get them to update the existing one (if it exists) ?
|
66
|
renderer.appendChild(head, link);
|
67
|
} catch (e) {
|
68
|
console.error('Error within linkService : ', e);
|
69
|
}
|
70
|
}
|
71
|
|
72
|
}
|
73
|
removeLinkForNextURL() {
|
74
|
this.removeLink("relnext", "next");
|
75
|
}
|
76
|
removeLinkForPrevURL() {
|
77
|
this.removeLink("relprev", "prev");
|
78
|
}
|
79
|
removeLink( id:string, relname:string) {
|
80
|
if(this.doc && (typeof this.doc.getElementById === "function" || typeof this.doc.createElement === "function") ){
|
81
|
if (typeof this.doc.getElementById === "function") {
|
82
|
let currentLink: HTMLLinkElement = this.doc.getElementById(id);
|
83
|
if(currentLink ){
|
84
|
currentLink.setAttribute('href', "");
|
85
|
currentLink.setAttribute('rel', "");
|
86
|
return ;
|
87
|
}
|
88
|
}
|
89
|
|
90
|
|
91
|
}
|
92
|
|
93
|
}
|
94
|
|
95
|
}
|
96
|
|
97
|
/*
|
98
|
* -- LinkService -- [Temporary]
|
99
|
* @MarkPieszak
|
100
|
*
|
101
|
* Similar to Meta service but made to handle <link> creation for SEO purposes
|
102
|
* -- NOTE: Soon there will be an overall DocumentService within Angular that handles Meta/Link everything
|
103
|
*/
|
104
|
//
|
105
|
// import { Injectable, Optional, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core';
|
106
|
// import { DOCUMENT } from '@angular/platform-browser';
|
107
|
//
|
108
|
// @Injectable()
|
109
|
// export class LinkService {
|
110
|
//
|
111
|
// constructor(
|
112
|
// private rendererFactory: RendererFactory2,
|
113
|
// @Inject(DOCUMENT) private document
|
114
|
// ) {
|
115
|
// }
|
116
|
|
117
|
/**
|
118
|
* Inject the State into the bottom of the <head>
|
119
|
*/
|
120
|
// addTag(tag: LinkDefinition, forceCreation?: boolean) {
|
121
|
//
|
122
|
// try {
|
123
|
// const renderer = this.rendererFactory.createRenderer(this.document, {
|
124
|
// id: '-1',
|
125
|
// encapsulation: ViewEncapsulation.None,
|
126
|
// styles: [],
|
127
|
// data: {}
|
128
|
// });
|
129
|
//
|
130
|
// const link = renderer.createElement('link');
|
131
|
// const head = this.document.head;
|
132
|
// const selector = this._parseSelector(tag);
|
133
|
//
|
134
|
// if (head === null) {
|
135
|
// throw new Error('<head> not found within DOCUMENT.');
|
136
|
// }
|
137
|
//
|
138
|
// Object.keys(tag).forEach((prop: string) => {
|
139
|
// return renderer.setAttribute(link, prop, tag[prop]);
|
140
|
// });
|
141
|
//
|
142
|
// // [TODO]: get them to update the existing one (if it exists) ?
|
143
|
// renderer.appendChild(head, link);
|
144
|
//
|
145
|
// } catch (e) {
|
146
|
// console.error('Error within linkService : ', e);
|
147
|
// }
|
148
|
// }
|
149
|
//
|
150
|
// private _parseSelector(tag: LinkDefinition): string {
|
151
|
// // Possibly re-work this
|
152
|
// const attr: string = tag.rel ? 'rel' : 'hreflang';
|
153
|
// return `${attr}="${tag[attr]}"`;
|
154
|
// }
|
155
|
// }
|
156
|
|
157
|
export declare type LinkDefinition = {
|
158
|
charset?: string;
|
159
|
crossorigin?: string;
|
160
|
href?: string;
|
161
|
hreflang?: string;
|
162
|
media?: string;
|
163
|
rel?: string;
|
164
|
rev?: string;
|
165
|
sizes?: string;
|
166
|
target?: string;
|
167
|
type?: string;
|
168
|
} & {
|
169
|
[prop: string]: string;
|
170
|
};
|