jsduck 4.10.4 → 5.0.0.beta01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. data/.travis.yml +0 -1
  2. data/README.md +32 -6
  3. data/Rakefile +10 -18
  4. data/bin/compare +5 -5
  5. data/bin/jsduck +2 -3
  6. data/jsduck.gemspec +3 -4
  7. data/lib/jsduck/aggregator.rb +21 -80
  8. data/lib/jsduck/app.rb +7 -14
  9. data/lib/jsduck/app_data.rb +4 -5
  10. data/lib/jsduck/assets.rb +4 -7
  11. data/lib/jsduck/base_type.rb +53 -0
  12. data/lib/jsduck/batch_parser.rb +8 -87
  13. data/lib/jsduck/batch_processor.rb +77 -0
  14. data/lib/jsduck/categories/auto.rb +83 -0
  15. data/lib/jsduck/categories/class_name.rb +63 -0
  16. data/lib/jsduck/categories/factory.rb +113 -0
  17. data/lib/jsduck/categories/file.rb +75 -0
  18. data/lib/jsduck/class.rb +3 -9
  19. data/lib/jsduck/class_doc_expander.rb +1 -1
  20. data/lib/jsduck/css/lexer.rb +203 -0
  21. data/lib/jsduck/css/parser.rb +121 -0
  22. data/lib/jsduck/doc/comment.rb +40 -0
  23. data/lib/jsduck/doc/map.rb +23 -0
  24. data/lib/jsduck/doc/parser.rb +128 -0
  25. data/lib/jsduck/doc/processor.rb +52 -0
  26. data/lib/jsduck/doc/scanner.rb +76 -0
  27. data/lib/jsduck/doc/standard_tag_parser.rb +154 -0
  28. data/lib/jsduck/doc/subproperties.rb +64 -0
  29. data/lib/jsduck/docs_code_comparer.rb +31 -0
  30. data/lib/jsduck/export_writer.rb +2 -2
  31. data/lib/jsduck/exporter/app.rb +16 -4
  32. data/lib/jsduck/exporter/full.rb +2 -2
  33. data/lib/jsduck/format/batch.rb +58 -0
  34. data/lib/jsduck/format/class.rb +62 -0
  35. data/lib/jsduck/format/doc.rb +172 -0
  36. data/lib/jsduck/format/html_stack.rb +109 -0
  37. data/lib/jsduck/format/shortener.rb +55 -0
  38. data/lib/jsduck/format/subproperties.rb +64 -0
  39. data/lib/jsduck/guides.rb +32 -14
  40. data/lib/jsduck/index_html.rb +3 -1
  41. data/lib/jsduck/inline/auto_link.rb +2 -2
  42. data/lib/jsduck/inline/link.rb +4 -3
  43. data/lib/jsduck/inline/link_renderer.rb +2 -2
  44. data/lib/jsduck/inline/video.rb +8 -2
  45. data/lib/jsduck/js/ast.rb +361 -0
  46. data/lib/jsduck/js/esprima.rb +39 -0
  47. data/lib/jsduck/{esprima → js/esprima}/esprima.js +0 -0
  48. data/lib/jsduck/js/evaluator.rb +70 -0
  49. data/lib/jsduck/js/ext_patterns.rb +70 -0
  50. data/lib/jsduck/js/function.rb +206 -0
  51. data/lib/jsduck/js/node.rb +194 -0
  52. data/lib/jsduck/js/node_array.rb +36 -0
  53. data/lib/jsduck/js/parser.rb +223 -0
  54. data/lib/jsduck/js/serializer.rb +263 -0
  55. data/lib/jsduck/js/utils.rb +21 -0
  56. data/lib/jsduck/logger.rb +3 -13
  57. data/lib/jsduck/members_index.rb +3 -4
  58. data/lib/jsduck/merger.rb +25 -145
  59. data/lib/jsduck/options.rb +29 -132
  60. data/lib/jsduck/parser.rb +76 -0
  61. data/lib/jsduck/process/accessors.rb +133 -0
  62. data/lib/jsduck/process/circular_deps.rb +58 -0
  63. data/lib/jsduck/process/enums.rb +91 -0
  64. data/lib/jsduck/process/ext4_events.rb +43 -0
  65. data/lib/jsduck/process/global_members.rb +36 -0
  66. data/lib/jsduck/process/ignored_classes.rb +16 -0
  67. data/lib/jsduck/process/importer.rb +58 -0
  68. data/lib/jsduck/process/inherit_doc.rb +197 -0
  69. data/lib/jsduck/process/lint.rb +135 -0
  70. data/lib/jsduck/process/overrides.rb +99 -0
  71. data/lib/jsduck/process/return_values.rb +72 -0
  72. data/lib/jsduck/process/versions.rb +102 -0
  73. data/lib/jsduck/relations.rb +5 -0
  74. data/lib/jsduck/render/class.rb +144 -0
  75. data/lib/jsduck/render/sidebar.rb +97 -0
  76. data/lib/jsduck/render/signature.rb +94 -0
  77. data/lib/jsduck/render/subproperties.rb +99 -0
  78. data/lib/jsduck/render/tags.rb +38 -0
  79. data/lib/jsduck/search_data.rb +19 -13
  80. data/lib/jsduck/source/file.rb +8 -17
  81. data/lib/jsduck/tag/abstract.rb +4 -7
  82. data/lib/jsduck/tag/accessor.rb +10 -0
  83. data/lib/jsduck/tag/alias.rb +61 -0
  84. data/lib/jsduck/tag/alternate_class_names.rb +17 -0
  85. data/lib/jsduck/tag/aside.rb +28 -31
  86. data/lib/jsduck/tag/author.rb +9 -5
  87. data/lib/jsduck/tag/boolean_tag.rb +24 -0
  88. data/lib/jsduck/tag/cfg.rb +45 -0
  89. data/lib/jsduck/tag/chainable.rb +5 -7
  90. data/lib/jsduck/tag/class.rb +28 -0
  91. data/lib/jsduck/tag/class_list_tag.rb +40 -0
  92. data/lib/jsduck/tag/constructor.rb +24 -0
  93. data/lib/jsduck/tag/css_mixin.rb +17 -0
  94. data/lib/jsduck/tag/css_var.rb +29 -0
  95. data/lib/jsduck/tag/default.rb +31 -0
  96. data/lib/jsduck/tag/deprecated.rb +13 -27
  97. data/lib/jsduck/tag/deprecated_tag.rb +58 -0
  98. data/lib/jsduck/tag/doc.rb +32 -0
  99. data/lib/jsduck/tag/docauthor.rb +4 -5
  100. data/lib/jsduck/tag/enum.rb +70 -0
  101. data/lib/jsduck/tag/event.rb +28 -0
  102. data/lib/jsduck/tag/evented.rb +10 -0
  103. data/lib/jsduck/tag/extends.rb +45 -0
  104. data/lib/jsduck/tag/ftype.rb +18 -0
  105. data/lib/jsduck/tag/hide.rb +4 -11
  106. data/lib/jsduck/tag/ignore.rb +6 -7
  107. data/lib/jsduck/tag/inheritable.rb +10 -0
  108. data/lib/jsduck/tag/inheritdoc.rb +48 -0
  109. data/lib/jsduck/tag/markdown.rb +8 -6
  110. data/lib/jsduck/tag/member.rb +24 -0
  111. data/lib/jsduck/tag/method.rb +35 -0
  112. data/lib/jsduck/tag/mixins.rb +26 -0
  113. data/lib/jsduck/tag/name.rb +36 -0
  114. data/lib/jsduck/tag/new.rb +13 -27
  115. data/lib/jsduck/tag/override.rb +37 -0
  116. data/lib/jsduck/tag/overrides.rb +29 -0
  117. data/lib/jsduck/tag/param.rb +87 -0
  118. data/lib/jsduck/tag/preventable.rb +19 -10
  119. data/lib/jsduck/tag/private.rb +28 -13
  120. data/lib/jsduck/tag/property.rb +39 -0
  121. data/lib/jsduck/tag/protected.rb +5 -7
  122. data/lib/jsduck/tag/ptype.rb +18 -0
  123. data/lib/jsduck/tag/readonly.rb +4 -7
  124. data/lib/jsduck/tag/removed.rb +21 -29
  125. data/lib/jsduck/tag/required.rb +11 -9
  126. data/lib/jsduck/tag/requires.rb +12 -0
  127. data/lib/jsduck/tag/return.rb +47 -0
  128. data/lib/jsduck/tag/since.rb +19 -11
  129. data/lib/jsduck/tag/singleton.rb +15 -0
  130. data/lib/jsduck/tag/static.rb +5 -7
  131. data/lib/jsduck/tag/subproperties.rb +23 -0
  132. data/lib/jsduck/tag/tag.rb +208 -0
  133. data/lib/jsduck/tag/template.rb +14 -9
  134. data/lib/jsduck/tag/throws.rb +38 -0
  135. data/lib/jsduck/tag/type.rb +48 -0
  136. data/lib/jsduck/tag/uses.rb +12 -0
  137. data/lib/jsduck/tag/xtype.rb +30 -0
  138. data/lib/jsduck/tag_loader.rb +39 -0
  139. data/lib/jsduck/tag_registry.rb +189 -0
  140. data/lib/jsduck/type_parser.rb +3 -3
  141. data/lib/jsduck/web_writer.rb +2 -2
  142. data/lib/jsduck/welcome.rb +1 -1
  143. metadata +578 -538
  144. data/lib/jsduck/accessors.rb +0 -136
  145. data/lib/jsduck/ast.rb +0 -524
  146. data/lib/jsduck/auto_categories.rb +0 -80
  147. data/lib/jsduck/batch_formatter.rb +0 -60
  148. data/lib/jsduck/categories.rb +0 -73
  149. data/lib/jsduck/categories_class_name.rb +0 -37
  150. data/lib/jsduck/circular_deps.rb +0 -56
  151. data/lib/jsduck/class_formatter.rb +0 -102
  152. data/lib/jsduck/columns.rb +0 -56
  153. data/lib/jsduck/css_lexer.rb +0 -201
  154. data/lib/jsduck/css_parser.rb +0 -119
  155. data/lib/jsduck/doc_ast.rb +0 -319
  156. data/lib/jsduck/doc_formatter.rb +0 -142
  157. data/lib/jsduck/doc_parser.rb +0 -611
  158. data/lib/jsduck/doc_type.rb +0 -59
  159. data/lib/jsduck/enum.rb +0 -73
  160. data/lib/jsduck/esprima.rb +0 -51
  161. data/lib/jsduck/evaluator.rb +0 -69
  162. data/lib/jsduck/ext_patterns.rb +0 -58
  163. data/lib/jsduck/file_categories.rb +0 -76
  164. data/lib/jsduck/function_ast.rb +0 -206
  165. data/lib/jsduck/guide_anchors.rb +0 -32
  166. data/lib/jsduck/guide_toc.rb +0 -49
  167. data/lib/jsduck/html_stack.rb +0 -105
  168. data/lib/jsduck/importer.rb +0 -121
  169. data/lib/jsduck/inherit_doc.rb +0 -193
  170. data/lib/jsduck/js_parser.rb +0 -221
  171. data/lib/jsduck/lint.rb +0 -133
  172. data/lib/jsduck/meta_tag.rb +0 -88
  173. data/lib/jsduck/meta_tag_loader.rb +0 -67
  174. data/lib/jsduck/meta_tag_registry.rb +0 -111
  175. data/lib/jsduck/meta_tag_renderer.rb +0 -34
  176. data/lib/jsduck/news.rb +0 -128
  177. data/lib/jsduck/override.rb +0 -87
  178. data/lib/jsduck/renderer.rb +0 -361
  179. data/lib/jsduck/return_values.rb +0 -72
  180. data/lib/jsduck/serializer.rb +0 -262
  181. data/lib/jsduck/shortener.rb +0 -58
  182. data/lib/jsduck/signature_renderer.rb +0 -91
  183. data/lib/jsduck/source/file_parser.rb +0 -72
@@ -0,0 +1,72 @@
1
+ module JsDuck
2
+ module Process
3
+
4
+ # Auto-detector return values and @chainable tags.
5
+ #
6
+ # Adds @chainable tag when doc-comment contains @return {OwnerClass}
7
+ # this. Also the other way around: when @chainable found, adds
8
+ # appropriate @return.
9
+ class ReturnValues
10
+ def initialize(relations)
11
+ @relations = relations
12
+ @cls = nil
13
+ end
14
+
15
+ def process_all!
16
+ @relations.each do |cls|
17
+ @cls = cls
18
+ cls.find_members(:tagname => :method, :local => true, :static => false).each do |m|
19
+ process(m)
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def process(m)
27
+ if constructor?(m)
28
+ add_return_new(m)
29
+ elsif chainable?(m)
30
+ add_return_this(m)
31
+ elsif returns_this?(m)
32
+ add_chainable(m)
33
+ end
34
+ end
35
+
36
+ def constructor?(m)
37
+ m[:name] == "constructor"
38
+ end
39
+
40
+ def chainable?(m)
41
+ m[:chainable]
42
+ end
43
+
44
+ def returns_this?(m)
45
+ m[:return] && m[:return][:type] == @cls[:name] && m[:return][:doc] =~ /\Athis\b/
46
+ end
47
+
48
+ def add_chainable(m)
49
+ m[:chainable] = true
50
+ end
51
+
52
+ def add_return_this(m)
53
+ if m[:return] == nil
54
+ m[:return] = {:type => @cls[:name], :doc => "this"}
55
+ end
56
+ end
57
+
58
+ def add_return_new(m)
59
+ if m[:return] == nil || m[:return][:type] == "Object"
60
+ # Create a whole new :return hash.
61
+ # If we were to just change the :type field it would modify
62
+ # the type of all the inherited constructor docs.
63
+ m[:return] = {
64
+ :type => @cls[:name],
65
+ :doc => m[:return] ? m[:return][:doc] : "",
66
+ }
67
+ end
68
+ end
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,102 @@
1
+ require 'jsduck/process/importer'
2
+ require 'jsduck/tag_registry'
3
+
4
+ module JsDuck
5
+ module Process
6
+
7
+ # Generates @since and @new tags by importing JSDuck exports of
8
+ # older versions of the same project and looking in which version
9
+ # a class or method first appeared.
10
+ #
11
+ # Additionally here the tooltip text for @new tag gets injected.
12
+ class Versions
13
+ def initialize(relations, opts={}, importer=nil)
14
+ @relations = relations
15
+ @opts = opts
16
+ # Allow different importer to be injected for testing
17
+ @importer = importer || Process::Importer.new
18
+ end
19
+
20
+ # Loads in exported docs and generates @since and @new tags.
21
+ def process_all!
22
+ init_new_tag_tooltip!
23
+
24
+ if @opts[:imports].length > 0
25
+ generate_since_tags(@importer.import(@opts[:imports]))
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ # Initializes the tooltip text for the signature of @new tag.
32
+ def init_new_tag_tooltip!
33
+ signature = TagRegistry.get_by_name(:new).signature
34
+ if @opts[:new_since]
35
+ signature[:tooltip] = "New since #{@opts[:new_since]}"
36
+ elsif @opts[:imports].length > 0
37
+ signature[:tooltip] = "New since #{@opts[:imports].last[:version]}"
38
+ end
39
+ end
40
+
41
+ # Using the imported versions data, adds @since tags to all
42
+ # classes/members.
43
+ def generate_since_tags(versions)
44
+ new_versions = build_new_versions_map(versions)
45
+
46
+ @relations.each do |cls|
47
+ v = cls[:since] || class_since(versions, cls)
48
+ cls[:since] = v
49
+ cls[:new] = true if new_versions[v]
50
+
51
+ cls.all_local_members.each do |m|
52
+ v = m[:since] || member_since(versions, cls, m)
53
+ m[:since] = v
54
+ m[:new] = true if new_versions[v]
55
+ end
56
+ end
57
+ end
58
+
59
+ # Generates a lookup table of versions that we are going to label
60
+ # with @new tags. By default we use the latest version, otherwise
61
+ # use all versions since the latest.
62
+ def build_new_versions_map(versions)
63
+ new_versions = {}
64
+
65
+ if @opts[:new_since]
66
+ versions.map {|v| v[:version] }.each do |v|
67
+ if v == @opts[:new_since] || !new_versions.empty?
68
+ new_versions[v] = true
69
+ end
70
+ end
71
+ else
72
+ new_versions[versions.last[:version]] = true
73
+ end
74
+
75
+ new_versions
76
+ end
77
+
78
+ def member_since(versions, cls, m)
79
+ versions.each do |ver|
80
+ c = ver[:classes][cls[:name]]
81
+ return ver[:version] if c && c[m[:id]]
82
+ cls[:alternateClassNames].each do |name|
83
+ c = ver[:classes][name]
84
+ return ver[:version] if c && c[m[:id]]
85
+ end
86
+ end
87
+ end
88
+
89
+ # Returns name of the version since which the class is available
90
+ def class_since(versions, cls)
91
+ versions.each do |ver|
92
+ return ver[:version] if ver[:classes][cls[:name]]
93
+ cls[:alternateClassNames].each do |name|
94
+ return ver[:version] if ver[:classes][name]
95
+ end
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+ end
@@ -50,6 +50,11 @@ module JsDuck
50
50
  @classes.each(&block)
51
51
  end
52
52
 
53
+ # Used in tests to check the nr of classes.
54
+ def length
55
+ @classes.length
56
+ end
57
+
53
58
  # Returns list of all classes. This method allows us to treat
54
59
  # Relations as array and therefore easily mock it
55
60
  def to_a
@@ -0,0 +1,144 @@
1
+ require 'jsduck/render/signature'
2
+ require 'jsduck/render/tags'
3
+ require 'jsduck/render/sidebar'
4
+
5
+ module JsDuck
6
+ module Render
7
+
8
+ # Renders the whole documentation page for a class.
9
+ class Class
10
+ def initialize(opts)
11
+ @opts = opts
12
+ end
13
+
14
+ def render(cls)
15
+ @cls = cls
16
+ @signature = Render::Signature.new(cls)
17
+
18
+ return [
19
+ "<div>",
20
+ render_sidebar,
21
+ "<div class='doc-contents'>",
22
+ render_tags(@cls),
23
+ "</div>",
24
+ "<div class='members'>",
25
+ render_all_sections,
26
+ "</div>",
27
+ "</div>",
28
+ ].flatten.compact.join
29
+ end
30
+
31
+ private
32
+
33
+ def render_tags(member)
34
+ Render::Tags.render(member)
35
+ end
36
+
37
+ def render_sidebar
38
+ Render::Sidebar.new(@opts).render(@cls)
39
+ end
40
+
41
+ def render_all_sections
42
+ TagRegistry.member_types.map do |member_type|
43
+ render_section(member_type)
44
+ end
45
+ end
46
+
47
+ def render_section(sec)
48
+ members = @cls[:members][sec[:name]] + @cls[:statics][sec[:name]]
49
+
50
+ # Skip rendering empty sections
51
+ return [] if members.length == 0
52
+
53
+ # Split members array into subsections
54
+ subsections = Array(sec[:subsections]).map do |subsec|
55
+ ms = members.find_all {|m| test_filter(m, subsec[:filter]) }
56
+ if ms.length > 0
57
+ {:title => subsec[:title], :members => ms, :default => subsec[:default]}
58
+ else
59
+ nil
60
+ end
61
+ end.compact
62
+
63
+ # Print no subsections when no subsections defined or there's
64
+ # just single subsection which is the default one.
65
+ if subsections.length == 0 || subsections.length == 1 && subsections[0][:default]
66
+ return [
67
+ "<div class='members-section'>",
68
+ "<div class='definedBy'>Defined By</div>",
69
+ "<h3 class='members-title icon-#{sec[:name]}'>#{sec[:title]}</h3>",
70
+ render_subsection(members, nil),
71
+ "</div>",
72
+ ]
73
+ end
74
+
75
+ return [
76
+ "<div class='members-section'>",
77
+ "<h3 class='members-title icon-#{sec[:name]}'>#{sec[:title]}</h3>",
78
+ subsections.map {|ss| render_subsection(ss[:members], ss[:title]) },
79
+ "</div>",
80
+ ]
81
+ end
82
+
83
+ # Returns true if member matches the conditions described by a
84
+ # subsection filter.
85
+ def test_filter(member, filter)
86
+ filter.each_pair do |field, truthy|
87
+ return false unless truthy ? member[field] : !member[field]
88
+ end
89
+ return true
90
+ end
91
+
92
+ def render_subsection(members, title)
93
+ return if members.length == 0
94
+ index = 0
95
+ return [
96
+ "<div class='subsection'>",
97
+ title ? "<div class='definedBy'>Defined By</div><h4 class='members-subtitle'>#{title}</h3>" : "",
98
+ members.map {|m| index += 1; render_member(m, index == 1) },
99
+ "</div>",
100
+ ]
101
+ end
102
+
103
+ def render_member(m, is_first)
104
+ # use classname "first-child" when it's first member in its category
105
+ first_child = is_first ? "first-child" : ""
106
+ # shorthand to owner class
107
+ owner = m[:owner]
108
+ # is this method inherited from parent?
109
+ inherited = (owner != @cls[:name])
110
+
111
+ return [
112
+ "<div id='#{m[:id]}' class='member #{first_child} #{inherited ? 'inherited' : 'not-inherited'}'>",
113
+ # leftmost column: expand button
114
+ "<a href='#' class='side expandable'>",
115
+ "<span>&nbsp;</span>",
116
+ "</a>",
117
+ # member name and type + link to owner class and source
118
+ "<div class='title'>",
119
+ "<div class='meta'>",
120
+ inherited ? "<a href='#!/api/#{owner}' rel='#{owner}' class='defined-in docClass'>#{owner}</a>" :
121
+ "<span class='defined-in' rel='#{owner}'>#{owner}</span>",
122
+ "<br/>",
123
+ @opts.source ? "<a href='source/#{m[:files][0][:href]}' target='_blank' class='view-source'>view source</a>" : "",
124
+ "</div>",
125
+ # method params signature or property type signature
126
+ @signature.render(m),
127
+ "</div>",
128
+ # short and long descriptions
129
+ "<div class='description'>",
130
+ "<div class='short'>",
131
+ m[:short_doc] ? m[:short_doc] : m[:doc],
132
+ "</div>",
133
+ "<div class='long'>",
134
+ render_tags(m),
135
+ "</div>",
136
+ "</div>",
137
+ "</div>",
138
+ ]
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,97 @@
1
+ module JsDuck
2
+ module Render
3
+
4
+ # Generates HTML for the class hierarchy sidebar inside class
5
+ # documentation.
6
+ class Sidebar
7
+ def initialize(opts)
8
+ @opts = opts
9
+ end
10
+
11
+ # Renders a sidebar for given class.
12
+ # Returns Array of HTML or nil.
13
+ def render(cls)
14
+ items = [
15
+ render_alternate_class_names(cls[:alternateClassNames]),
16
+ render_tree(cls),
17
+ render_dependencies(cls[:mixins], "Mixins"),
18
+ render_dependencies(cls[:parentMixins], "Inherited mixins"),
19
+ render_dependencies(cls[:requires], "Requires"),
20
+ render_dependencies(cls[:subclasses], "Subclasses"),
21
+ render_dependencies(cls[:mixedInto], "Mixed into"),
22
+ render_dependencies(cls[:uses], "Uses"),
23
+ render_files(cls[:files])
24
+ ]
25
+
26
+ if items.compact.length > 0
27
+ return ['<pre class="hierarchy">', items, '</pre>']
28
+ else
29
+ return nil
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def render_alternate_class_names(names)
36
+ return if names.length == 0
37
+
38
+ return [
39
+ "<h4>Alternate names</h4>",
40
+ names.map {|name| "<div class='alternate-class-name'>#{name}</div>" },
41
+ ]
42
+ end
43
+
44
+ def render_dependencies(names, title)
45
+ return if !names || names.length == 0
46
+
47
+ return [
48
+ "<h4>#{title}</h4>",
49
+ names.map {|name| "<div class='dependency'>#{name.exists? ? render_link(name) : name}</div>" },
50
+ ]
51
+ end
52
+
53
+ def render_files(files)
54
+ return if !@opts.source || files.length == 0 || files[0][:filename] == ""
55
+
56
+ return [
57
+ "<h4>Files</h4>",
58
+ files.map do |file|
59
+ url = "source/" + file[:href]
60
+ title = File.basename(file[:filename])
61
+ "<div class='dependency'><a href='#{url}' target='_blank'>#{title}</a></div>"
62
+ end
63
+ ]
64
+ end
65
+
66
+ # Take care of the special case where class has parent for which we have no docs.
67
+ # In that case the "extends" property exists but "superclasses" is empty.
68
+ # We still create the tree, but without links in it.
69
+ def render_tree(cls)
70
+ return if !cls[:extends] || cls[:extends] == "Object"
71
+
72
+ return [
73
+ "<h4>Hierarchy</h4>",
74
+ render_class_tree(cls[:superclasses] + [cls[:name]])
75
+ ]
76
+ end
77
+
78
+ def render_class_tree(classes, i=0)
79
+ return "" if classes.length <= i
80
+
81
+ name = classes[i]
82
+ return [
83
+ "<div class='subclass #{i == 0 ? 'first-child' : ''}'>",
84
+ classes.length-1 == i ? "<strong>#{name}</strong>" : (name.exists? ? render_link(name) : name),
85
+ render_class_tree(classes, i+1),
86
+ "</div>",
87
+ ]
88
+ end
89
+
90
+ def render_link(cls_name)
91
+ "<a href='#!/api/#{cls_name}' rel='#{cls_name}' class='docClass'>#{cls_name}</a>"
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,94 @@
1
+ require 'jsduck/render/tags'
2
+ require 'jsduck/tag_registry'
3
+
4
+ module JsDuck
5
+ module Render
6
+
7
+ # Performs the rendering of member signatures.
8
+ class Signature
9
+ # Initializes the renderer for rendering members of the given
10
+ # class.
11
+ def initialize(cls)
12
+ @cls = cls
13
+ end
14
+
15
+ # Renders signature of the given member.
16
+ def render(member)
17
+ # Keep the code simpler by not passing around the member hash
18
+ @m = member
19
+
20
+ return [
21
+ render_new,
22
+ render_link,
23
+ render_type,
24
+ render_tag_signature,
25
+ ]
26
+ end
27
+
28
+ private
29
+
30
+ def render_new
31
+ constructor? ? "<strong class='new-keyword'>new</strong>" : ""
32
+ end
33
+
34
+ def render_link
35
+ "<a href='#{render_url}' class='name #{render_expandable}'>#{render_name}</a>"
36
+ end
37
+
38
+ def render_url
39
+ "#!/api/#{@m[:owner]}-#{@m[:id]}"
40
+ end
41
+
42
+ def render_expandable
43
+ @m[:short_doc] ? "expandable" : "not-expandable"
44
+ end
45
+
46
+ def render_name
47
+ constructor? ? @cls[:name] : @m[:name]
48
+ end
49
+
50
+ def constructor?
51
+ @m[:tagname] == :method && @m[:name] == "constructor"
52
+ end
53
+
54
+ def render_type
55
+ if like_property?
56
+ render_property_type
57
+ else
58
+ render_params + render_return
59
+ end
60
+ end
61
+
62
+ def like_property?
63
+ TagRegistry.member_type_names(:property_like).include?(@m[:tagname])
64
+ end
65
+
66
+ def render_property_type
67
+ "<span> : #{@m[:html_type]}</span>"
68
+ end
69
+
70
+ def render_params
71
+ ps = @m[:params].map {|p| render_single_param(p) }.join(", ")
72
+ "( <span class='pre'>#{ps}</span> )"
73
+ end
74
+
75
+ def render_single_param(param)
76
+ param[:optional] ? "["+param[:name]+"]" : param[:name]
77
+ end
78
+
79
+ def render_return
80
+ method_with_return? ? (" : " + @m[:return][:html_type]) : ""
81
+ end
82
+
83
+ def method_with_return?
84
+ @m[:tagname] == :method && @m[:return] != nil
85
+ end
86
+
87
+ def render_tag_signature
88
+ Render::Tags.render_signature(@m)
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+ end