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.
- data/.travis.yml +0 -1
- data/README.md +32 -6
- data/Rakefile +10 -18
- data/bin/compare +5 -5
- data/bin/jsduck +2 -3
- data/jsduck.gemspec +3 -4
- data/lib/jsduck/aggregator.rb +21 -80
- data/lib/jsduck/app.rb +7 -14
- data/lib/jsduck/app_data.rb +4 -5
- data/lib/jsduck/assets.rb +4 -7
- data/lib/jsduck/base_type.rb +53 -0
- data/lib/jsduck/batch_parser.rb +8 -87
- data/lib/jsduck/batch_processor.rb +77 -0
- data/lib/jsduck/categories/auto.rb +83 -0
- data/lib/jsduck/categories/class_name.rb +63 -0
- data/lib/jsduck/categories/factory.rb +113 -0
- data/lib/jsduck/categories/file.rb +75 -0
- data/lib/jsduck/class.rb +3 -9
- data/lib/jsduck/class_doc_expander.rb +1 -1
- data/lib/jsduck/css/lexer.rb +203 -0
- data/lib/jsduck/css/parser.rb +121 -0
- data/lib/jsduck/doc/comment.rb +40 -0
- data/lib/jsduck/doc/map.rb +23 -0
- data/lib/jsduck/doc/parser.rb +128 -0
- data/lib/jsduck/doc/processor.rb +52 -0
- data/lib/jsduck/doc/scanner.rb +76 -0
- data/lib/jsduck/doc/standard_tag_parser.rb +154 -0
- data/lib/jsduck/doc/subproperties.rb +64 -0
- data/lib/jsduck/docs_code_comparer.rb +31 -0
- data/lib/jsduck/export_writer.rb +2 -2
- data/lib/jsduck/exporter/app.rb +16 -4
- data/lib/jsduck/exporter/full.rb +2 -2
- data/lib/jsduck/format/batch.rb +58 -0
- data/lib/jsduck/format/class.rb +62 -0
- data/lib/jsduck/format/doc.rb +172 -0
- data/lib/jsduck/format/html_stack.rb +109 -0
- data/lib/jsduck/format/shortener.rb +55 -0
- data/lib/jsduck/format/subproperties.rb +64 -0
- data/lib/jsduck/guides.rb +32 -14
- data/lib/jsduck/index_html.rb +3 -1
- data/lib/jsduck/inline/auto_link.rb +2 -2
- data/lib/jsduck/inline/link.rb +4 -3
- data/lib/jsduck/inline/link_renderer.rb +2 -2
- data/lib/jsduck/inline/video.rb +8 -2
- data/lib/jsduck/js/ast.rb +361 -0
- data/lib/jsduck/js/esprima.rb +39 -0
- data/lib/jsduck/{esprima → js/esprima}/esprima.js +0 -0
- data/lib/jsduck/js/evaluator.rb +70 -0
- data/lib/jsduck/js/ext_patterns.rb +70 -0
- data/lib/jsduck/js/function.rb +206 -0
- data/lib/jsduck/js/node.rb +194 -0
- data/lib/jsduck/js/node_array.rb +36 -0
- data/lib/jsduck/js/parser.rb +223 -0
- data/lib/jsduck/js/serializer.rb +263 -0
- data/lib/jsduck/js/utils.rb +21 -0
- data/lib/jsduck/logger.rb +3 -13
- data/lib/jsduck/members_index.rb +3 -4
- data/lib/jsduck/merger.rb +25 -145
- data/lib/jsduck/options.rb +29 -132
- data/lib/jsduck/parser.rb +76 -0
- data/lib/jsduck/process/accessors.rb +133 -0
- data/lib/jsduck/process/circular_deps.rb +58 -0
- data/lib/jsduck/process/enums.rb +91 -0
- data/lib/jsduck/process/ext4_events.rb +43 -0
- data/lib/jsduck/process/global_members.rb +36 -0
- data/lib/jsduck/process/ignored_classes.rb +16 -0
- data/lib/jsduck/process/importer.rb +58 -0
- data/lib/jsduck/process/inherit_doc.rb +197 -0
- data/lib/jsduck/process/lint.rb +135 -0
- data/lib/jsduck/process/overrides.rb +99 -0
- data/lib/jsduck/process/return_values.rb +72 -0
- data/lib/jsduck/process/versions.rb +102 -0
- data/lib/jsduck/relations.rb +5 -0
- data/lib/jsduck/render/class.rb +144 -0
- data/lib/jsduck/render/sidebar.rb +97 -0
- data/lib/jsduck/render/signature.rb +94 -0
- data/lib/jsduck/render/subproperties.rb +99 -0
- data/lib/jsduck/render/tags.rb +38 -0
- data/lib/jsduck/search_data.rb +19 -13
- data/lib/jsduck/source/file.rb +8 -17
- data/lib/jsduck/tag/abstract.rb +4 -7
- data/lib/jsduck/tag/accessor.rb +10 -0
- data/lib/jsduck/tag/alias.rb +61 -0
- data/lib/jsduck/tag/alternate_class_names.rb +17 -0
- data/lib/jsduck/tag/aside.rb +28 -31
- data/lib/jsduck/tag/author.rb +9 -5
- data/lib/jsduck/tag/boolean_tag.rb +24 -0
- data/lib/jsduck/tag/cfg.rb +45 -0
- data/lib/jsduck/tag/chainable.rb +5 -7
- data/lib/jsduck/tag/class.rb +28 -0
- data/lib/jsduck/tag/class_list_tag.rb +40 -0
- data/lib/jsduck/tag/constructor.rb +24 -0
- data/lib/jsduck/tag/css_mixin.rb +17 -0
- data/lib/jsduck/tag/css_var.rb +29 -0
- data/lib/jsduck/tag/default.rb +31 -0
- data/lib/jsduck/tag/deprecated.rb +13 -27
- data/lib/jsduck/tag/deprecated_tag.rb +58 -0
- data/lib/jsduck/tag/doc.rb +32 -0
- data/lib/jsduck/tag/docauthor.rb +4 -5
- data/lib/jsduck/tag/enum.rb +70 -0
- data/lib/jsduck/tag/event.rb +28 -0
- data/lib/jsduck/tag/evented.rb +10 -0
- data/lib/jsduck/tag/extends.rb +45 -0
- data/lib/jsduck/tag/ftype.rb +18 -0
- data/lib/jsduck/tag/hide.rb +4 -11
- data/lib/jsduck/tag/ignore.rb +6 -7
- data/lib/jsduck/tag/inheritable.rb +10 -0
- data/lib/jsduck/tag/inheritdoc.rb +48 -0
- data/lib/jsduck/tag/markdown.rb +8 -6
- data/lib/jsduck/tag/member.rb +24 -0
- data/lib/jsduck/tag/method.rb +35 -0
- data/lib/jsduck/tag/mixins.rb +26 -0
- data/lib/jsduck/tag/name.rb +36 -0
- data/lib/jsduck/tag/new.rb +13 -27
- data/lib/jsduck/tag/override.rb +37 -0
- data/lib/jsduck/tag/overrides.rb +29 -0
- data/lib/jsduck/tag/param.rb +87 -0
- data/lib/jsduck/tag/preventable.rb +19 -10
- data/lib/jsduck/tag/private.rb +28 -13
- data/lib/jsduck/tag/property.rb +39 -0
- data/lib/jsduck/tag/protected.rb +5 -7
- data/lib/jsduck/tag/ptype.rb +18 -0
- data/lib/jsduck/tag/readonly.rb +4 -7
- data/lib/jsduck/tag/removed.rb +21 -29
- data/lib/jsduck/tag/required.rb +11 -9
- data/lib/jsduck/tag/requires.rb +12 -0
- data/lib/jsduck/tag/return.rb +47 -0
- data/lib/jsduck/tag/since.rb +19 -11
- data/lib/jsduck/tag/singleton.rb +15 -0
- data/lib/jsduck/tag/static.rb +5 -7
- data/lib/jsduck/tag/subproperties.rb +23 -0
- data/lib/jsduck/tag/tag.rb +208 -0
- data/lib/jsduck/tag/template.rb +14 -9
- data/lib/jsduck/tag/throws.rb +38 -0
- data/lib/jsduck/tag/type.rb +48 -0
- data/lib/jsduck/tag/uses.rb +12 -0
- data/lib/jsduck/tag/xtype.rb +30 -0
- data/lib/jsduck/tag_loader.rb +39 -0
- data/lib/jsduck/tag_registry.rb +189 -0
- data/lib/jsduck/type_parser.rb +3 -3
- data/lib/jsduck/web_writer.rb +2 -2
- data/lib/jsduck/welcome.rb +1 -1
- metadata +578 -538
- data/lib/jsduck/accessors.rb +0 -136
- data/lib/jsduck/ast.rb +0 -524
- data/lib/jsduck/auto_categories.rb +0 -80
- data/lib/jsduck/batch_formatter.rb +0 -60
- data/lib/jsduck/categories.rb +0 -73
- data/lib/jsduck/categories_class_name.rb +0 -37
- data/lib/jsduck/circular_deps.rb +0 -56
- data/lib/jsduck/class_formatter.rb +0 -102
- data/lib/jsduck/columns.rb +0 -56
- data/lib/jsduck/css_lexer.rb +0 -201
- data/lib/jsduck/css_parser.rb +0 -119
- data/lib/jsduck/doc_ast.rb +0 -319
- data/lib/jsduck/doc_formatter.rb +0 -142
- data/lib/jsduck/doc_parser.rb +0 -611
- data/lib/jsduck/doc_type.rb +0 -59
- data/lib/jsduck/enum.rb +0 -73
- data/lib/jsduck/esprima.rb +0 -51
- data/lib/jsduck/evaluator.rb +0 -69
- data/lib/jsduck/ext_patterns.rb +0 -58
- data/lib/jsduck/file_categories.rb +0 -76
- data/lib/jsduck/function_ast.rb +0 -206
- data/lib/jsduck/guide_anchors.rb +0 -32
- data/lib/jsduck/guide_toc.rb +0 -49
- data/lib/jsduck/html_stack.rb +0 -105
- data/lib/jsduck/importer.rb +0 -121
- data/lib/jsduck/inherit_doc.rb +0 -193
- data/lib/jsduck/js_parser.rb +0 -221
- data/lib/jsduck/lint.rb +0 -133
- data/lib/jsduck/meta_tag.rb +0 -88
- data/lib/jsduck/meta_tag_loader.rb +0 -67
- data/lib/jsduck/meta_tag_registry.rb +0 -111
- data/lib/jsduck/meta_tag_renderer.rb +0 -34
- data/lib/jsduck/news.rb +0 -128
- data/lib/jsduck/override.rb +0 -87
- data/lib/jsduck/renderer.rb +0 -361
- data/lib/jsduck/return_values.rb +0 -72
- data/lib/jsduck/serializer.rb +0 -262
- data/lib/jsduck/shortener.rb +0 -58
- data/lib/jsduck/signature_renderer.rb +0 -91
- 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
|
data/lib/jsduck/relations.rb
CHANGED
@@ -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> </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
|