1 | /* |
2 | Copyright - 2021 - wwwouaiebe - Contact: https://www.ouaie.be/ |
3 | |
4 | This program is free software; |
5 | you can redistribute it and/or modify it under the terms of the |
6 | GNU General Public License as published by the Free Software Foundation; |
7 | either version 3 of the License, or any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | /* |
19 | Changes: |
20 | - v1.0.0: |
21 | - created |
22 | - v1.1.0: |
23 | - Issue ♯3 : String.substr ( ) is deprecated... Replace... |
24 | Doc reviewed 20211111 |
25 | */ |
26 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
27 | |
28 | import { marked } from 'marked'; |
29 | |
30 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
31 | /** |
32 | Store all the links created from the source document and get the links completed with the path for others classes |
33 | */ |
34 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
35 | |
36 | class LinkBuilder { |
37 | |
38 | /** |
39 | A cache for the sources links |
40 | @type {Array.<Array.<String>>} |
41 | */ |
42 | |
43 | #sourcesLinksCache; |
44 | |
45 | /** |
46 | The links to the sources files |
47 | @type {Map.<String>} |
48 | */ |
49 | |
50 | #sourcesLinks; |
51 | |
52 | /** |
53 | A cache for the classes links |
54 | @type {Array.<Array.<String>>} |
55 | */ |
56 | |
57 | #classesLinksCache; |
58 | |
59 | /** |
60 | The links to the classes files |
61 | @type {Map.<String>} |
62 | */ |
63 | |
64 | #classesLinks; |
65 | |
66 | /** |
67 | A cache for the variables links |
68 | @type {Array.<Array.<String>>} |
69 | */ |
70 | |
71 | #variablesLinksCache; |
72 | |
73 | /** |
74 | The links to the variables file and the variables in the file |
75 | @type {Map.<String>} |
76 | */ |
77 | |
78 | #variablesLinks; |
79 | |
80 | /** |
81 | The links to the mdn documentation |
82 | @type {Object} |
83 | */ |
84 | |
85 | #mdnLinks = Object.freeze ( |
86 | { |
87 | |
88 | // Global objects |
89 | Array : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array', |
90 | ArrayBuffer : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer', |
91 | Boolean : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean', |
92 | Error : 'https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Error', |
93 | Function : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function', |
94 | Map : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map', |
95 | Number : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number', |
96 | Object : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object', |
97 | Promise : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise', |
98 | RegExp : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp', |
99 | String : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String', |
100 | Uint8Array : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array', |
101 | |
102 | // Statements |
103 | Class : 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class', |
104 | |
105 | // API |
106 | CryptoKey : 'https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey', |
107 | Event : 'https://developer.mozilla.org/en-US/docs/Web/API/Event', |
108 | GeolocationPosition : 'https://developer.mozilla.org/fr/docs/Web/API/GeolocationPosition', |
109 | GeolocationPositionError : 'https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError', |
110 | IDBFactory : 'https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory', |
111 | HTMLElement : 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement', |
112 | Node : 'https://developer.mozilla.org/en-US/docs/Web/API/Node', |
113 | NodeList : 'https://developer.mozilla.org/fr/docs/Web/API/NodeList', |
114 | SVGElement : 'https://developer.mozilla.org/en-US/docs/Web/API/SVGElement', |
115 | XMLDocument : 'https://developer.mozilla.org/en-US/docs/Web/API/XMLDocument', |
116 | |
117 | // Others |
118 | LeafletObject : 'https://leafletjs.com/reference.html', |
119 | OsmElement : 'https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL', |
120 | JsonObject : 'https://www.json.org/json-en.html' |
121 | } |
122 | ); |
123 | |
124 | /** |
125 | The constructor |
126 | */ |
127 | |
128 | constructor ( ) { |
129 | Object.freeze ( this ); |
130 | this.#sourcesLinks = new Map ( ); |
131 | this.#classesLinks = new Map ( ); |
132 | this.#variablesLinks = new Map ( ); |
133 | } |
134 | |
135 | /** |
136 | Get the html link to a class file |
137 | @param {String} className The name of the class for witch the link must be created |
138 | @param {String} rootPath The path between the file where the link will be inserted and theConfig.destDir |
139 | ( something like '../../../', depending of the folders tree ) |
140 | @return {String} An html string with the link or the className when the link is not found |
141 | */ |
142 | |
143 | getClassLink ( className, rootPath ) { |
144 | const classLink = this.#classesLinks.get ( className ); |
145 | return classLink ? `<a href="${rootPath + classLink}">${className}</a>` : className; |
146 | } |
147 | |
148 | /** |
149 | Store a link to a class file |
150 | @param {ClassDoc} classDoc the doc with the class documentation |
151 | */ |
152 | |
153 | setClassLink ( classDoc ) { |
154 | this.#classesLinks.set ( |
155 | classDoc.name, |
156 | classDoc.file.substring ( 0, classDoc.file.lastIndexOf ( '/' ) + 1 ) + classDoc.name + '.html' |
157 | ); |
158 | } |
159 | |
160 | /** |
161 | Get all the classes links. Each subAray contains the class name and the class link. |
162 | @type {Array.<Array.<String>>} |
163 | */ |
164 | |
165 | get classesLinks ( ) { |
166 | if ( ! this.#classesLinksCache ) { |
167 | |
168 | // Create the cache if not exists |
169 | this.#classesLinksCache = this.#classesLinksCache ?? Array.from ( this.#classesLinks ).sort ( |
170 | ( first, second ) => first [ 0 ] .localeCompare ( second [ 0 ] ) |
171 | ); |
172 | } |
173 | |
174 | return this.#classesLinksCache; |
175 | } |
176 | |
177 | /** |
178 | Get a link to a source file |
179 | @param {VariableDoc|MethodOrPropertyDoc|VariableDoc} doc The doc for witch the link to the source file must be created. |
180 | @return {?String} The link to the source file |
181 | */ |
182 | |
183 | getSourceLink ( doc ) { |
184 | let sourceLink = this.#sourcesLinks.get ( doc.file ); |
185 | if ( sourceLink ) { |
186 | return doc.rootPath + sourceLink + '#L' + String ( doc.line ).padStart ( 5, '_' ); |
187 | } |
188 | return null; |
189 | } |
190 | |
191 | /** |
192 | Store a link to a source file |
193 | @param {String} fileName The file name |
194 | @param {String} path The path since theConfig.destDir, included file name |
195 | */ |
196 | |
197 | setSourceLink ( fileName, path ) { |
198 | this.#sourcesLinks.set ( fileName, path ); |
199 | } |
200 | |
201 | /** |
202 | Get all the sources links. Each subAray contains the source file name and the path |
203 | between theConfig.destDir and the source file, included file name |
204 | @type {Array.<Array.<String>>} |
205 | */ |
206 | |
207 | get sourcesLinks ( ) { |
208 | if ( ! this.#sourcesLinksCache ) { |
209 | this.#sourcesLinksCache = Array.from ( this.#sourcesLinks ).sort ( |
210 | ( first, second ) => first [ 0 ] .localeCompare ( second [ 0 ] ) |
211 | ); |
212 | } |
213 | return this.#sourcesLinksCache; |
214 | } |
215 | |
216 | /** |
217 | Store a link to a variable in the variables.html file |
218 | @param {VariableDoc} variableDoc the doc with the variable documentation |
219 | */ |
220 | |
221 | setVariableLink ( variableDoc ) { |
222 | this.#variablesLinks.set ( |
223 | variableDoc.name, |
224 | `variables.html#${variableDoc.name}` |
225 | ); |
226 | } |
227 | |
228 | /** |
229 | Get all the variables links. Each subAray contains the variable name and the variable link. |
230 | @type {Array.<Array.<String>>} |
231 | */ |
232 | |
233 | get variablesLinks ( ) { |
234 | if ( ! this.#variablesLinksCache ) { |
235 | this.#variablesLinksCache = Array.from ( this.#variablesLinks ).sort ( |
236 | ( first, second ) => first [ 0 ] .localeCompare ( second [ 0 ] ) |
237 | ); |
238 | } |
239 | return this.#variablesLinksCache; |
240 | } |
241 | |
242 | /** |
243 | Get the link to a type |
244 | @param {String} type The type for witch the link must be created. Must be a single word |
245 | @param {String} rootPath The path between the file where the link will be inserted and theConfig.destDir |
246 | ( something like '../../../', depending of the folders tree ) |
247 | @return {String} The link to the type. We search first in the classes links, then in the mdn links. If nothing |
248 | found, the type without html link is returned. |
249 | */ |
250 | |
251 | #getTypeLink ( type, rootPath ) { |
252 | if ( 'constructor' === type ) { |
253 | return type; |
254 | } |
255 | const classLink = this.#classesLinks.get ( type ); |
256 | if ( classLink ) { |
257 | return `<a href="${rootPath + classLink}">${type}</a>`; |
258 | } |
259 | const mdnLink = this.#mdnLinks [ type ]; |
260 | if ( mdnLink ) { |
261 | return `<a href="${mdnLink}">${type}</a>`; |
262 | } |
263 | const variableLink = this.#variablesLinks.get ( type ); |
264 | if ( variableLink ) { |
265 | return `<a href="${variableLink}">${type}</a>`; |
266 | } |
267 | return type; |
268 | } |
269 | |
270 | /** |
271 | Verify that a given type is a known type ( = present in the @classesLinks map |
272 | or the mdnLinks object |
273 | @param {String} type The type to verify |
274 | @return {Boolean} True when the type is known |
275 | */ |
276 | |
277 | isKnownType ( type ) { |
278 | return Boolean ( this.#classesLinks.get ( type ) || this.#mdnLinks [ type ] ); |
279 | } |
280 | |
281 | /** |
282 | Get the links to a type |
283 | @param {String} type The types for witch the link must be created. Can be multiple word |
284 | @param {String} rootPath The path between the file where the link will be inserted and theConfig.destDir |
285 | ( something like '../../../', depending of the folders tree ) |
286 | @return {String} The html links to the types. We search first in the classes links, then in the mdn links. If nothing |
287 | found, the types without html link is returned. |
288 | */ |
289 | |
290 | getTypeLinks ( type, rootPath ) { |
291 | if ( ! type ) { |
292 | return 'null'; |
293 | } |
294 | let returnType = ''; |
295 | type.split ( ' ' ).forEach ( |
296 | tmpType => returnType += this.#getTypeLink ( tmpType, rootPath ) + ' ' |
297 | ); |
298 | |
299 | return returnType.trimEnd ( ); |
300 | } |
301 | |
302 | /** |
303 | Add links to a description |
304 | @param {String} desc The description to complete with links |
305 | @param {String} rootPath The path between the file where the link will be inserted and theConfig.destDir |
306 | ( something like '../../../', depending of the folders tree ) |
307 | @return {String} The description completed with html links |
308 | */ |
309 | |
310 | getDescLink ( desc, rootPath ) { |
311 | let returnDesc = ''; |
312 | desc.split ( ' ' ).forEach ( |
313 | word => returnDesc += this.#getTypeLink ( word, rootPath ) + ' ' |
314 | ); |
315 | return marked.parse ( returnDesc.trimEnd ( ) ); |
316 | } |
317 | } |
318 | |
319 | /** |
320 | The one and only one instance of LinkBuilder class |
321 | @type {LinkBuilder} |
322 | */ |
323 | |
324 | const theLinkBuilder = new LinkBuilder ( ); |
325 | |
326 | export default theLinkBuilder; |
327 | |
328 | /* --- End of file --------------------------------------------------------------------------------------------------------- */ |
329 |