readme: add information section
[nit.git] / src / web / model_html.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Translate mentities to html blocks.
16 module model_html
17
18 import model
19 import model::model_collect
20 import doc::doc_down
21 import html::bootstrap
22
23 redef class MEntity
24
25 # Returns the MEntity name escaped for html.
26 #
27 # * MPackage: `foo`
28 # * MGroup: `foo`
29 # * MModule: `foo`
30 # * MClass: `Foo[E]`
31 # * MClassDef: `Foo[E]`
32 # * MProperty: `foo(e)`
33 # * MPropdef: `foo(e)`
34 var html_name: String is lazy do return name.html_escape
35
36 # MEntity namespace escaped for html.
37 fun html_raw_namespace: String is abstract
38
39 # Link to MEntity in the web server.
40 # TODO this should be parameterizable... but how?
41 fun html_link: Link do return new Link("/doc/{html_raw_namespace}", html_name)
42
43 # Returns the list of keyword used in `self` declaration.
44 fun html_modifiers: Array[String] is abstract
45
46 # Returns the complete MEntity declaration decorated with HTML.
47 #
48 # * MPackage: `package foo`
49 # * MGroup: `group foo`
50 # * MModule: `module foo`
51 # * MClass: `private abstract class Foo[E: Object]`
52 # * MClassDef: `redef class Foo[E]`
53 # * MProperty: `private fun foo(e: Object): Int`
54 # * MPropdef: `redef fun foo(e)`
55 fun html_declaration: Template do
56 var tpl = new Template
57 tpl.add "<span>"
58 tpl.add html_modifiers.join(" ")
59 tpl.add " "
60 tpl.add html_link
61 tpl.add "</span>"
62 return tpl
63 end
64
65 # Returns `self` namespace decorated with HTML links.
66 #
67 # * MPackage: `mpackage`
68 # * MGroup: `mpackage(::group)`
69 # * MModule: `mgroup::mmodule`
70 # * MClass: `mpackage::mclass`
71 # * MClassDef: `mmodule::mclassdef`
72 # * MProperty: `mclass::mprop`
73 # * MPropdef: `mclassdef:mpropdef`
74 fun html_namespace: Template is abstract
75
76 # Returns the synopsis and the comment of this MEntity formatted as HTML.
77 var html_documentation: nullable Writable is lazy do
78 var mdoc = mdoc_or_fallback
79 if mdoc == null then return null
80 return mdoc.html_documentation
81 end
82
83 # Returns the synopsis of this MEntity formatted as HTML.
84 var html_synopsis: nullable Writable is lazy do
85 var mdoc = mdoc_or_fallback
86 if mdoc == null then return null
87 return mdoc.html_synopsis
88 end
89
90 # Returns the the comment without the synopsis formatted as HTML.
91 var html_comment: nullable Writable is lazy do
92 var mdoc = mdoc_or_fallback
93 if mdoc == null then return null
94 return mdoc.html_comment
95 end
96
97 # Icon that will be displayed before the title
98 fun html_icon: BSIcon do
99 var icon = new BSIcon("tag")
100 icon.css_classes.add_all(css_classes)
101 return icon
102 end
103
104 # CSS classes used to decorate `self`.
105 #
106 # Mainly used for icons.
107 var css_classes = new Array[String]
108
109 # HTML Tree containing all the nested element of `self`.
110 #
111 # The nested elements depend on the type of `self`:
112 # `MPackage`: root mgroup
113 # `MGroup`: directly nested mgroups, mmodules
114 # `MModule`: mclassdefs
115 # `MClassDef`: mpropdefs
116 fun html_tree: UnorderedList do
117 var list = new UnorderedList
118 list.add_li html_tree_li
119 return list
120 end
121
122 # HTML Tree list item used by `html_tree`.
123 private fun html_tree_li: ListItem do return new ListItem(html_link)
124 end
125
126
127 redef class MPackage
128 redef fun html_raw_namespace do return html_name
129
130 redef fun html_tree_li do
131 var tpl = new Template
132 tpl.add html_link
133 var list = new UnorderedList
134 var root = self.root
135 if root != null then
136 list.add_li root.html_tree_li
137 end
138 tpl.add list
139 return new ListItem(tpl)
140 end
141
142 redef var html_modifiers = ["package"]
143 redef fun html_namespace do return html_link
144 redef var css_classes = ["public"]
145 end
146
147 redef class MGroup
148 redef fun html_raw_namespace do
149 var parent = self.parent
150 if parent != null then
151 return "{parent.html_raw_namespace}::{html_name}"
152 end
153 return "{mpackage.html_raw_namespace}::{html_name}"
154 end
155
156 redef var html_modifiers = ["group"]
157
158 # Depends if `self` is root or not.
159 #
160 # * If root `mpackage`.
161 # * Else `mpackage::self`.
162 redef fun html_namespace do
163 var tpl = new Template
164 tpl.add mpackage.html_namespace
165 if mpackage.root != self then
166 tpl.add "::"
167 tpl.add html_link
168 end
169 return tpl
170 end
171
172 redef var css_classes = ["public"]
173
174 redef fun html_tree_li do
175 var tpl = new Template
176 tpl.add html_link
177 var list = new UnorderedList
178 for mgroup in in_nesting.direct_smallers do
179 list.add_li mgroup.html_tree_li
180 end
181 for mmodule in mmodules do
182 list.add_li mmodule.html_tree_li
183 end
184 tpl.add list
185 return new ListItem(tpl)
186 end
187 end
188
189 redef class MModule
190
191 redef var html_modifiers = ["module"]
192
193 # Depends if `self` belongs to a MGroup.
194 #
195 # * If mgroup `mgroup::self`.
196 # * Else `self`.
197 redef fun html_namespace do
198 var mgroup = self.mgroup
199 var tpl = new Template
200 if mgroup != null then
201 tpl.add mgroup.html_namespace
202 tpl.add "::"
203 end
204 tpl.add html_link
205 return tpl
206 end
207
208 redef fun html_raw_namespace do
209 var mpackage = self.mpackage
210 var mgroup = self.mgroup
211 if mgroup != null then
212 return "{mgroup.html_raw_namespace}::{html_name}"
213 else if mpackage != null then
214 return "{mpackage.html_raw_namespace}::{html_name}"
215 end
216 return html_name
217 end
218
219 redef var css_classes = ["public"]
220
221 redef fun html_tree_li do
222 var tpl = new Template
223 tpl.add html_link
224 var list = new UnorderedList
225 for mclassdef in mclassdefs do
226 list.add_li mclassdef.html_tree_li
227 end
228 tpl.add list
229 return new ListItem(tpl)
230 end
231 end
232
233 redef class MClass
234 redef fun mdoc_or_fallback do return intro.mdoc
235
236 # Format: `Foo[E]`
237 redef var html_name is lazy do
238 var tpl = new Template
239 tpl.add name.html_escape
240 if arity > 0 then
241 tpl.add "["
242 var parameter_names = new Array[String]
243 for p in mparameters do
244 parameter_names.add(p.html_name)
245 end
246 tpl.add parameter_names.join(", ")
247 tpl.add "]"
248 end
249 return tpl.write_to_string
250 end
251
252 redef fun html_modifiers do return intro.html_modifiers
253 redef fun html_declaration do return intro.html_declaration
254
255 # Returns `mpackage::self`.
256 redef fun html_namespace do
257 var mgroup = intro_mmodule.mgroup
258 var tpl = new Template
259 if mgroup != null then
260 tpl.add mgroup.mpackage.html_namespace
261 tpl.add "::"
262 end
263 tpl.add "<span>"
264 tpl.add html_link
265 tpl.add "</span>"
266 return tpl
267 end
268
269 redef fun html_raw_namespace do return intro.html_raw_namespace
270
271 # Returns `intro.html_short_signature`.
272 fun html_short_signature: Template do return intro.html_short_signature
273
274 # Returns `intro.html_signature`.
275 fun html_signature: Template do return intro.html_signature
276
277 redef fun html_icon do return intro.html_icon
278 redef fun css_classes do return intro.css_classes
279 end
280
281 redef class MClassDef
282 redef fun html_raw_namespace do return "{mmodule.html_raw_namespace}::{html_name}"
283
284 redef fun html_tree_li do
285 var tpl = new Template
286 tpl.add html_link
287 var list = new UnorderedList
288 for mpropdef in mpropdefs do
289 list.add_li mpropdef.html_tree_li
290 end
291 tpl.add list
292 return new ListItem(tpl)
293 end
294
295 redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback
296
297 # Depends if `self` is an intro or not.
298 #
299 # * If intro contains the visibility and kind.
300 # * If redef contains the `redef` keyword and kind.
301 redef fun html_modifiers do
302 var res = new Array[String]
303 if not is_intro then
304 res.add "redef"
305 else
306 if mclass.visibility != public_visibility then
307 res.add mclass.visibility.to_s
308 end
309 end
310 res.add mclass.kind.to_s
311 return res
312 end
313
314 # Depends if `self` is an intro or not.
315 #
316 # For intro: `private abstract class Foo[E: Object]`
317 # For redef: `redef class Foo[E]`
318 redef fun html_declaration do
319 var tpl = new Template
320 tpl.add "<span>"
321 tpl.add html_modifiers.join(" ")
322 tpl.add " "
323 tpl.add html_link
324 if is_intro then
325 tpl.add html_signature
326 else
327 tpl.add html_short_signature
328 end
329 tpl.add "</span>"
330 return tpl
331 end
332
333 # Returns `mmodule::self`
334 redef fun html_namespace do
335 var tpl = new Template
336 tpl.add mmodule.html_namespace
337 tpl.add "::<span>"
338 tpl.add mclass.html_link
339 tpl.add "</span>"
340 return tpl
341 end
342
343 # Returns the MClassDef generic signature without static bounds.
344 fun html_short_signature: Template do
345 var tpl = new Template
346 var mparameters = mclass.mparameters
347 if not mparameters.is_empty then
348 tpl.add "["
349 for i in [0..mparameters.length[ do
350 tpl.add mparameters[i].html_name
351 if i < mparameters.length - 1 then tpl.add ", "
352 end
353 tpl.add "]"
354 end
355 return tpl
356 end
357
358 # Returns the MClassDef generic signature with static bounds.
359 fun html_signature: Template do
360 var tpl = new Template
361 var mparameters = mclass.mparameters
362 if not mparameters.is_empty then
363 tpl.add "["
364 for i in [0..mparameters.length[ do
365 tpl.add "{mparameters[i].html_name}: "
366 tpl.add bound_mtype.arguments[i].html_signature
367 if i < mparameters.length - 1 then tpl.add ", "
368 end
369 tpl.add "]"
370 end
371 return tpl
372 end
373
374 redef fun css_classes do
375 var set = new HashSet[String]
376 if is_intro then set.add "intro"
377 for m in mclass.intro.collect_modifiers do set.add m.to_cmangle
378 for m in collect_modifiers do set.add m.to_cmangle
379 return set.to_a
380 end
381 end
382
383 redef class MProperty
384 redef fun mdoc_or_fallback do return intro.mdoc
385 redef fun html_modifiers do return intro.html_modifiers
386 redef fun html_declaration do return intro.html_declaration
387
388 # Returns `mclass::self`.
389 redef fun html_namespace do
390 var tpl = new Template
391 tpl.add intro_mclassdef.mclass.html_namespace
392 tpl.add "::<span>"
393 tpl.add intro.html_link
394 tpl.add "</span>"
395 return tpl
396 end
397
398 redef fun html_raw_namespace do return intro.html_raw_namespace
399
400 # Returns `intro.html_short_signature`.
401 fun html_short_signature: Template do return intro.html_short_signature
402
403 # Returns `intro.html_signature`.
404 fun html_signature: Template do return intro.html_signature
405
406 redef fun css_classes do return intro.css_classes
407 end
408
409 redef class MPropDef
410 redef fun html_raw_namespace do return "{mclassdef.html_raw_namespace}::{html_name}"
411 redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback
412
413 # Depends if `self` is an intro or not.
414 #
415 # * If intro contains the visibility and kind.
416 # * If redef contains the `redef` keyword and kind.
417 redef fun html_modifiers do
418 var res = new Array[String]
419 if not is_intro then
420 res.add "redef"
421 else
422 if mproperty.visibility != public_visibility then
423 res.add mproperty.visibility.to_s
424 end
425 end
426 return res
427 end
428
429 # Depends if `self` is an intro or not.
430 #
431 # For intro: `private fun foo(e: Object): Bar is abstract`
432 # For redef: `redef fun foo(e) is cached`
433 redef fun html_declaration do
434 var tpl = new Template
435 tpl.add "<span>"
436 tpl.add html_modifiers.join(" ")
437 tpl.add " "
438 if is_intro then
439 tpl.add html_link
440 tpl.add html_signature
441 else
442 tpl.add mproperty.intro.html_link
443 tpl.add html_short_signature
444 end
445 tpl.add "</span>"
446 return tpl
447 end
448
449 # Returns `mclassdef::self`
450 redef fun html_namespace do
451 var tpl = new Template
452 tpl.add mclassdef.html_namespace
453 tpl.add "::"
454 tpl.add html_link
455 return tpl
456 end
457
458 # Returns the MPropdDef signature without static types.
459 fun html_short_signature: Template is abstract
460
461 # Returns the MPropDef signature with static types.
462 fun html_signature: Template is abstract
463
464 redef fun css_classes do
465 var set = new HashSet[String]
466 if is_intro then set.add "intro"
467 for m in mproperty.intro.collect_modifiers do set.add m.to_cmangle
468 for m in collect_modifiers do set.add m.to_cmangle
469 return set.to_a
470 end
471 end
472
473 redef class MAttributeDef
474
475 redef fun html_modifiers do
476 var res = super
477 res.add "var"
478 return res
479 end
480
481 redef fun html_short_signature do return new Template
482
483 redef fun html_signature do
484 var static_mtype = self.static_mtype
485 var tpl = new Template
486 if static_mtype != null then
487 tpl.add ": "
488 tpl.add static_mtype.html_signature
489 end
490 return tpl
491 end
492 end
493
494 redef class MMethodDef
495
496 # FIXME annotation should be handled in their own way
497 redef fun html_modifiers do
498 if mproperty.is_init then
499 var res = new Array[String]
500 if mproperty.visibility != public_visibility then
501 res.add mproperty.visibility.to_s
502 end
503 return res
504 end
505 var res = super
506 if is_abstract then
507 res.add "abstract"
508 else if is_intern then
509 res.add "intern"
510 end
511 res.add "fun"
512 return res
513 end
514
515 redef fun html_declaration do
516 if mproperty.is_init then
517 var tpl = new Template
518 tpl.add "<span>"
519 tpl.add html_modifiers.join(" ")
520 tpl.add " "
521 tpl.add html_link
522 tpl.add html_signature
523 tpl.add "</span>"
524 return tpl
525 end
526 return super
527 end
528
529 redef fun html_short_signature do
530 var new_msignature = self.new_msignature
531 if mproperty.is_root_init and new_msignature != null then
532 return new_msignature.html_short_signature
533 end
534 return msignature.as(not null).html_short_signature
535 end
536
537 redef fun html_signature do
538 var new_msignature = self.new_msignature
539 if mproperty.is_root_init and new_msignature != null then
540 return new_msignature.html_signature
541 end
542 return msignature.as(not null).html_signature
543 end
544 end
545
546 redef class MVirtualTypeProp
547 redef fun html_link do return mvirtualtype.html_link
548 end
549
550 redef class MVirtualTypeDef
551
552 redef fun html_modifiers do
553 var res = super
554 res.add "type"
555 return res
556 end
557
558 redef fun html_short_signature do return new Template
559
560 redef fun html_signature do
561 var bound = self.bound
562 var tpl = new Template
563 if bound == null then return tpl
564 tpl.add ": "
565 tpl.add bound.html_signature
566 return tpl
567 end
568 end
569
570 redef class MType
571 # Returns the signature of this type whithout bounds.
572 fun html_short_signature: Template is abstract
573
574 # Returns the signature of this type.
575 fun html_signature: Template is abstract
576 end
577
578 redef class MClassType
579 redef fun html_link do return mclass.html_link
580 redef fun html_short_signature do return html_link
581 redef fun html_signature do return html_link
582 end
583
584 redef class MNullableType
585 redef fun html_short_signature do
586 var tpl = new Template
587 tpl.add "nullable "
588 tpl.add mtype.html_short_signature
589 return tpl
590 end
591
592 redef fun html_signature do
593 var tpl = new Template
594 tpl.add "nullable "
595 tpl.add mtype.html_signature
596 return tpl
597 end
598 end
599
600 redef class MGenericType
601 redef fun html_short_signature do
602 var lnk = html_link
603 var tpl = new Template
604 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
605 tpl.add "["
606 for i in [0..arguments.length[ do
607 tpl.add arguments[i].html_short_signature
608 if i < arguments.length - 1 then tpl.add ", "
609 end
610 tpl.add "]"
611 return tpl
612 end
613
614 redef fun html_signature do
615 var lnk = html_link
616 var tpl = new Template
617 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
618 tpl.add "["
619 for i in [0..arguments.length[ do
620 tpl.add arguments[i].html_signature
621 if i < arguments.length - 1 then tpl.add ", "
622 end
623 tpl.add "]"
624 return tpl
625 end
626 end
627
628 redef class MParameterType
629 redef fun html_short_signature do return html_link
630 redef fun html_signature do return html_link
631 redef fun html_raw_namespace do return html_name
632 end
633
634 redef class MVirtualType
635 redef fun html_signature do return html_link
636 redef fun html_raw_namespace do return html_name
637 end
638
639 redef class MSignature
640 redef fun html_short_signature do
641 var tpl = new Template
642 if not mparameters.is_empty then
643 tpl.add "("
644 for i in [0..mparameters.length[ do
645 tpl.add mparameters[i].html_short_signature
646 if i < mparameters.length - 1 then tpl.add ", "
647 end
648 tpl.add ")"
649 end
650 return tpl
651 end
652
653 redef fun html_signature do
654 var tpl = new Template
655 if not mparameters.is_empty then
656 tpl.add "("
657 for i in [0..mparameters.length[ do
658 tpl.add mparameters[i].html_signature
659 if i < mparameters.length - 1 then tpl.add ", "
660 end
661 tpl.add ")"
662 end
663 var return_mtype = self.return_mtype
664 if return_mtype != null then
665 tpl.add ": "
666 tpl.add return_mtype.html_signature
667 end
668 return tpl
669 end
670 end
671
672 redef class MParameter
673
674 # Returns `self` name and ellipsys if any.
675 fun html_short_signature: Template do
676 var tpl = new Template
677 tpl.add name
678 if is_vararg then tpl.add "..."
679 return tpl
680 end
681
682 # Returns `self` name with it's static type and ellipsys if any.
683 fun html_signature: Template do
684 var tpl = new Template
685 tpl.add "{name}: "
686 tpl.add mtype.html_signature
687 if is_vararg then tpl.add "..."
688 return tpl
689 end
690 end