jsduck 4.0.1 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. data/Rakefile +14 -0
  2. data/esprima/esprima.js +210 -85
  3. data/jsduck.gemspec +3 -3
  4. data/lib/jsduck/accessors.rb +10 -8
  5. data/lib/jsduck/aggregator.rb +7 -7
  6. data/lib/jsduck/app.rb +24 -164
  7. data/lib/jsduck/app_data.rb +2 -4
  8. data/lib/jsduck/assets.rb +5 -2
  9. data/lib/jsduck/ast.rb +9 -4
  10. data/lib/jsduck/batch_formatter.rb +54 -0
  11. data/lib/jsduck/batch_parser.rb +106 -0
  12. data/lib/jsduck/categories.rb +5 -6
  13. data/lib/jsduck/class.rb +77 -239
  14. data/lib/jsduck/class_doc_expander.rb +0 -5
  15. data/lib/jsduck/class_formatter.rb +14 -10
  16. data/lib/jsduck/class_name.rb +23 -0
  17. data/lib/jsduck/class_writer.rb +9 -8
  18. data/lib/jsduck/doc_ast.rb +5 -6
  19. data/lib/jsduck/doc_formatter.rb +61 -272
  20. data/lib/jsduck/enum.rb +4 -4
  21. data/lib/jsduck/esprima.rb +10 -4
  22. data/lib/jsduck/examples.rb +5 -5
  23. data/lib/jsduck/export_writer.rb +62 -0
  24. data/lib/jsduck/exporter/app.rb +62 -0
  25. data/lib/jsduck/exporter/examples.rb +58 -0
  26. data/lib/jsduck/exporter/full.rb +60 -0
  27. data/lib/jsduck/file_categories.rb +7 -4
  28. data/lib/jsduck/function_ast.rb +99 -0
  29. data/lib/jsduck/grouped_asset.rb +27 -16
  30. data/lib/jsduck/guide_writer.rb +8 -7
  31. data/lib/jsduck/guides.rb +31 -29
  32. data/lib/jsduck/icons.rb +12 -1
  33. data/lib/jsduck/images.rb +3 -3
  34. data/lib/jsduck/importer.rb +7 -7
  35. data/lib/jsduck/index_html.rb +20 -6
  36. data/lib/jsduck/inherit_doc.rb +9 -12
  37. data/lib/jsduck/inline/example.rb +42 -0
  38. data/lib/jsduck/inline/img.rb +55 -0
  39. data/lib/jsduck/inline/link.rb +227 -0
  40. data/lib/jsduck/inline/video.rb +67 -0
  41. data/lib/jsduck/inline_examples.rb +7 -7
  42. data/lib/jsduck/js_parser.rb +5 -4
  43. data/lib/jsduck/lint.rb +14 -2
  44. data/lib/jsduck/logger.rb +5 -6
  45. data/lib/jsduck/members_index.rb +132 -0
  46. data/lib/jsduck/merger.rb +3 -9
  47. data/lib/jsduck/options.rb +39 -41
  48. data/lib/jsduck/override.rb +3 -7
  49. data/lib/jsduck/relations.rb +9 -9
  50. data/lib/jsduck/renderer.rb +3 -3
  51. data/lib/jsduck/return_values.rb +72 -0
  52. data/lib/jsduck/search_data.rb +16 -20
  53. data/lib/jsduck/shortener.rb +58 -0
  54. data/lib/jsduck/signature_renderer.rb +1 -2
  55. data/lib/jsduck/source/file.rb +98 -0
  56. data/lib/jsduck/source/file_parser.rb +72 -0
  57. data/lib/jsduck/source/writer.rb +89 -0
  58. data/lib/jsduck/tag/aside.rb +1 -1
  59. data/lib/jsduck/tag/since.rb +1 -1
  60. data/lib/jsduck/template_dir.rb +2 -2
  61. data/lib/jsduck/util/html.rb +27 -0
  62. data/lib/jsduck/util/io.rb +32 -0
  63. data/lib/jsduck/util/json.rb +60 -0
  64. data/lib/jsduck/util/null_object.rb +23 -0
  65. data/lib/jsduck/util/os.rb +14 -0
  66. data/lib/jsduck/util/parallel.rb +34 -0
  67. data/lib/jsduck/util/singleton.rb +35 -0
  68. data/lib/jsduck/util/stdout.rb +33 -0
  69. data/lib/jsduck/videos.rb +5 -5
  70. data/lib/jsduck/web_writer.rb +79 -0
  71. data/lib/jsduck/welcome.rb +6 -6
  72. data/spec/class_factory.rb +20 -0
  73. metadata +32 -20
  74. data/lib/jsduck/api_exporter.rb +0 -48
  75. data/lib/jsduck/app_exporter.rb +0 -60
  76. data/lib/jsduck/examples_exporter.rb +0 -56
  77. data/lib/jsduck/full_exporter.rb +0 -35
  78. data/lib/jsduck/html.rb +0 -25
  79. data/lib/jsduck/inline_img.rb +0 -53
  80. data/lib/jsduck/inline_video.rb +0 -58
  81. data/lib/jsduck/io.rb +0 -30
  82. data/lib/jsduck/json_duck.rb +0 -52
  83. data/lib/jsduck/lexer.rb +0 -251
  84. data/lib/jsduck/null_object.rb +0 -19
  85. data/lib/jsduck/os.rb +0 -11
  86. data/lib/jsduck/parallel_wrap.rb +0 -32
  87. data/lib/jsduck/source_file.rb +0 -97
  88. data/lib/jsduck/source_file_parser.rb +0 -70
  89. data/lib/jsduck/source_writer.rb +0 -87
  90. data/lib/jsduck/stats.rb +0 -103
  91. data/lib/jsduck/stdout.rb +0 -31
@@ -10,20 +10,10 @@ module JsDuck
10
10
  class GroupedAsset
11
11
  # Should be called from constructor after @groups have been read in,
12
12
  # and after it's been ensured that all items in groupes have names.
13
- #
14
- # Prints warning when there is a duplicate item within a group.
15
- # The warning message should say something like "duplicate <asset type>"
16
- def build_map_by_name(warning_msg, filename)
13
+ def build_map_by_name
17
14
  @map_by_name = {}
18
- @groups.each do |group|
19
- group_map = {}
20
- group["items"].each do |item|
21
- if group_map[item["name"]]
22
- Logger.instance.warn(:dup_asset, "#{warning_msg} '#{item['name']}'", filename)
23
- end
24
- @map_by_name[item["name"]] = item
25
- group_map[item["name"]] = item
26
- end
15
+ each_item do |item|
16
+ @map_by_name[item["name"]] = item
27
17
  end
28
18
  end
29
19
 
@@ -33,9 +23,30 @@ module JsDuck
33
23
  end
34
24
 
35
25
  # Iterates over all items in all groups
36
- def each_item
37
- @groups.each do |group|
38
- group["items"].each {|item| yield item }
26
+ def each_item(group=nil, &block)
27
+ group = group || @groups
28
+
29
+ group.each do |item|
30
+ if item["items"]
31
+ each_item(item["items"], &block)
32
+ else
33
+ block.call(item)
34
+ end
35
+ end
36
+ end
37
+
38
+ def map_items(group=nil, &block)
39
+ group = group || @groups
40
+
41
+ group.map do |item|
42
+ if item["items"]
43
+ {
44
+ "title" => item["title"],
45
+ "items" => map_items(item["items"], &block)
46
+ }
47
+ else
48
+ block.call(item)
49
+ end
39
50
  end
40
51
  end
41
52
 
@@ -1,6 +1,7 @@
1
- require 'jsduck/parallel_wrap'
1
+ require 'jsduck/util/parallel'
2
+ require 'jsduck/util/stdout'
3
+ require 'jsduck/util/json'
2
4
  require 'jsduck/logger'
3
- require 'jsduck/stdout'
4
5
  require 'fileutils'
5
6
 
6
7
  module JsDuck
@@ -24,21 +25,21 @@ module JsDuck
24
25
 
25
26
  def write_stdout
26
27
  json = ParallelWrap.map(all_guides) {|guide| @exporter.export_guide(guide) }.compact
27
- Stdout.instance.add(json)
28
+ Util::Stdout.add(json)
28
29
  end
29
30
 
30
31
  def write_dir(dir, extension)
31
32
  FileUtils.mkdir(dir) unless File.exists?(dir)
32
- ParallelWrap.each(all_guides) do |guide|
33
+ Util::Parallel.each(all_guides) do |guide|
33
34
  filename = dir + "/" + guide["name"] + extension
34
- Logger.instance.log("Writing guide", filename)
35
+ Logger.log("Writing guide", filename)
35
36
  json = @exporter.export_guide(guide)
36
37
  # skip file if exporter returned nil
37
38
  if json
38
39
  if extension == ".json"
39
- JsonDuck.write_json(filename, json)
40
+ Util::Json.write_json(filename, json)
40
41
  elsif extension == ".js"
41
- JsonDuck.write_jsonp(filename, guide["name"], json)
42
+ Util::Json.write_jsonp(filename, guide["name"], json)
42
43
  else
43
44
  throw "Unexpected file extension: #{extension}"
44
45
  end
@@ -1,10 +1,10 @@
1
1
  require 'jsduck/logger'
2
- require 'jsduck/json_duck'
3
- require 'jsduck/io'
4
- require 'jsduck/null_object'
2
+ require 'jsduck/util/json'
3
+ require 'jsduck/util/io'
4
+ require 'jsduck/util/null_object'
5
5
  require 'jsduck/logger'
6
6
  require 'jsduck/grouped_asset'
7
- require 'jsduck/html'
7
+ require 'jsduck/util/html'
8
8
  require 'fileutils'
9
9
 
10
10
  module JsDuck
@@ -16,17 +16,18 @@ module JsDuck
16
16
  if filename
17
17
  Guides.new(filename, formatter, opts)
18
18
  else
19
- NullObject.new(:to_array => [], :to_html => "", :[] => nil)
19
+ Util::NullObject.new(:to_array => [], :to_html => "", :[] => nil)
20
20
  end
21
21
  end
22
22
 
23
23
  # Parses guides config file
24
24
  def initialize(filename, formatter, opts)
25
25
  @path = File.dirname(filename)
26
- @groups = JsonDuck.read(filename)
27
- build_map_by_name("Two guides have the same name", filename)
26
+ @groups = Util::Json.read(filename)
28
27
  @formatter = formatter
29
28
  @opts = opts
29
+ build_map_by_name
30
+ load_all_guides
30
31
  end
31
32
 
32
33
  # Writes all guides to given dir in JsonP format
@@ -35,43 +36,36 @@ module JsDuck
35
36
  each_item {|guide| write_guide(guide, dir) }
36
37
  end
37
38
 
38
- # Modified each_item that also loads HTML for each guide
39
- def each_item
40
- super do |guide|
41
- # Load the guide if not loaded
42
- guide[:html] = load_guide(guide) if guide[:html] == nil
43
- # Pass guide to block if it was successfully loaded.
44
- yield guide if guide[:html]
39
+ def load_all_guides
40
+ each_item do |guide|
41
+ guide[:html] = load_guide(guide)
45
42
  end
46
43
  end
47
44
 
48
45
  # Modified to_array that excludes the :html from guide nodes
49
46
  def to_array
50
- @groups.map do |group|
51
- {
52
- "title" => group["title"],
53
- "items" => group["items"].map {|g| Hash[g.select {|k, v| k != :html }] }
54
- }
47
+ map_items do |item|
48
+ Hash[item.select {|k, v| k != :html }]
55
49
  end
56
50
  end
57
51
 
58
52
  def load_guide(guide)
59
53
  in_dir = @path + "/guides/" + guide["name"]
60
54
 
61
- return Logger.instance.warn(:guide, "Guide not found", in_dir) unless File.exists?(in_dir)
55
+ return Logger.warn(:guide, "Guide not found", in_dir) unless File.exists?(in_dir)
62
56
 
63
57
  guide_file = in_dir + "/README.md"
64
58
 
65
- return Logger.instance.warn(:guide, "Guide not found", guide_file) unless File.exists?(guide_file)
59
+ return Logger.warn(:guide, "Guide not found", guide_file) unless File.exists?(guide_file)
66
60
 
67
61
  begin
68
62
  @formatter.doc_context = {:filename => guide_file, :linenr => 0}
69
63
  name = File.basename(in_dir)
70
64
  @formatter.img_path = "guides/#{name}"
71
65
 
72
- return add_toc(guide, @formatter.format(JsDuck::IO.read(guide_file)))
66
+ return add_toc(guide, @formatter.format(Util::IO.read(guide_file)))
73
67
  rescue
74
- Logger.instance.fatal_backtrace("Error while reading/formatting guide #{in_dir}", $!)
68
+ Logger.fatal_backtrace("Error while reading/formatting guide #{in_dir}", $!)
75
69
  exit(1)
76
70
  end
77
71
  end
@@ -82,14 +76,14 @@ module JsDuck
82
76
  in_dir = @path + "/guides/" + guide["name"]
83
77
  out_dir = dir + "/" + guide["name"]
84
78
 
85
- Logger.instance.log("Writing guide", out_dir)
79
+ Logger.log("Writing guide", out_dir)
86
80
  # Copy the whole guide dir over
87
81
  FileUtils.cp_r(in_dir, out_dir)
88
82
 
89
83
  # Ensure the guide has an icon
90
84
  fix_icon(out_dir)
91
85
 
92
- JsonDuck.write_jsonp(out_dir+"/README.js", guide["name"], {:guide => guide[:html], :title => guide["title"]})
86
+ Util::Json.write_jsonp(out_dir+"/README.js", guide["name"], {:guide => guide[:html], :title => guide["title"]})
93
87
  end
94
88
 
95
89
  # Ensures the guide dir contains icon.png.
@@ -117,7 +111,7 @@ module JsDuck
117
111
  html.each_line do |line|
118
112
  if line =~ /^<h2>(.*)<\/h2>$/
119
113
  i += 1
120
- text = HTML.strip_tags($1)
114
+ text = Util::HTML.strip_tags($1)
121
115
  toc << "<li><a href='#!/guide/#{guide['name']}-section-#{i}'>#{text}</a></li>\n"
122
116
  new_html << "<h2 id='#{guide['name']}-section-#{i}'>#{text}</h2>\n"
123
117
  else
@@ -136,23 +130,31 @@ module JsDuck
136
130
  end
137
131
 
138
132
  # Returns HTML listing of guides
139
- def to_html
133
+ def to_html(style="")
140
134
  html = @groups.map do |group|
141
135
  [
142
136
  "<h3>#{group['title']}</h3>",
143
137
  "<ul>",
144
- group["items"].map {|g| "<li><a href='#!/guide/#{g['name']}'>#{g['title']}</a></li>" },
138
+ flatten_subgroups(group["items"]).map {|g| "<li><a href='#!/guide/#{g['name']}'>#{g['title']}</a></li>" },
145
139
  "</ul>",
146
140
  ]
147
141
  end.flatten.join("\n")
148
142
 
149
143
  return <<-EOHTML
150
- <div id='guides-content' style='display:none'>
144
+ <div id='guides-content' style='#{style}'>
151
145
  #{html}
152
146
  </div>
153
147
  EOHTML
154
148
  end
155
149
 
150
+ def flatten_subgroups(items)
151
+ result = []
152
+ each_item(items) do |item|
153
+ result << item
154
+ end
155
+ result
156
+ end
157
+
156
158
  # Extracts guide icon URL from guide hash
157
159
  def icon_url(guide)
158
160
  "guides/" + guide["name"] + "/icon.png"
@@ -9,10 +9,21 @@ module JsDuck
9
9
  :name => cls[:name],
10
10
  :extends => cls[:extends],
11
11
  :private => cls[:private],
12
- :icon => cls.icon,
12
+ :icon => Icons::class_icon(cls),
13
13
  }
14
14
  end
15
15
  end
16
+
17
+ # Returns CSS class name for an icon of class
18
+ def self.class_icon(cls)
19
+ if cls[:singleton]
20
+ "icon-singleton"
21
+ elsif cls.inherits_from?("Ext.Component")
22
+ "icon-component"
23
+ else
24
+ "icon-class"
25
+ end
26
+ end
16
27
  end
17
28
 
18
29
  end
@@ -35,7 +35,7 @@ module JsDuck
35
35
  def copy(output_dir)
36
36
  @images.each_key do |img|
37
37
  unless copy_img(img, output_dir)
38
- Logger.instance.warn(:image, "Image not found.", img)
38
+ Logger.warn(:image, "Image not found.", img)
39
39
  end
40
40
  end
41
41
  report_unused
@@ -47,7 +47,7 @@ module JsDuck
47
47
  filename = path + "/" + img
48
48
  if map.has_key?(filename)
49
49
  dest = output_dir + "/" + img
50
- Logger.instance.log("Copying image", dest)
50
+ Logger.log("Copying image", dest)
51
51
  FileUtils.makedirs(File.dirname(dest))
52
52
  FileUtils.cp(filename, dest)
53
53
  # mark file as used.
@@ -62,7 +62,7 @@ module JsDuck
62
62
  def report_unused
63
63
  @paths.each_pair do |path, map|
64
64
  map.each_pair do |img, used|
65
- Logger.instance.warn(:image_unused, "Image not used.", img) unless used
65
+ Logger.warn(:image_unused, "Image not used.", img) unless used
66
66
  end
67
67
  end
68
68
  end
@@ -1,7 +1,7 @@
1
- require 'jsduck/json_duck'
2
- require 'jsduck/null_object'
1
+ require 'jsduck/util/json'
2
+ require 'jsduck/util/null_object'
3
3
  require 'jsduck/logger'
4
- require 'jsduck/parallel_wrap'
4
+ require 'jsduck/util/parallel'
5
5
 
6
6
  module JsDuck
7
7
 
@@ -29,15 +29,15 @@ module JsDuck
29
29
  end
30
30
 
31
31
  def current_version
32
- NullObject.new(:[] => NullObject.new(:[] => true))
32
+ Util::NullObject.new(:[] => Util::NullObject.new(:[] => true))
33
33
  end
34
34
 
35
35
  # Reads in data from all .json files in directory
36
36
  def read(ver)
37
37
  # Map list of files into pairs of (classname, members-hash)
38
- pairs = ParallelWrap.map(Dir[ver[:path] + "/*.json"]) do |filename|
39
- JsDuck::Logger.instance.log("Importing #{ver[:version]}", filename)
40
- json = JsonDuck.read(filename)
38
+ pairs = Util::Parallel.map(Dir[ver[:path] + "/*.json"]) do |filename|
39
+ JsDuck::Logger.log("Importing #{ver[:version]}", filename)
40
+ json = Util::Json.read(filename)
41
41
  [json["name"], members_id_index(json)]
42
42
  end
43
43
 
@@ -1,5 +1,5 @@
1
1
  require 'jsduck/logger'
2
- require 'jsduck/io'
2
+ require 'jsduck/util/io'
3
3
  require 'fileutils'
4
4
 
5
5
  module JsDuck
@@ -17,8 +17,10 @@ module JsDuck
17
17
  def write
18
18
  if @opts.seo
19
19
  FileUtils.cp(@opts.template_dir+"/index.php", @opts.output_dir+"/index.php")
20
+ FileUtils.cp(@opts.template_dir+"/Mobile_Detect.php", @opts.output_dir+"/Mobile_Detect.php")
20
21
  create_template_html(@opts.template_dir+"/template.html", @opts.output_dir+"/template.html")
21
22
  create_print_template_html(@opts.template_dir+"/print-template.html", @opts.output_dir+"/print-template.html")
23
+ create_index_template_html(@opts.template_dir+"/index-template.html", @opts.output_dir+"/index-template.html")
22
24
  else
23
25
  create_template_html(@opts.template_dir+"/template.html", @opts.output_dir+"/index.html")
24
26
  end
@@ -32,9 +34,9 @@ module JsDuck
32
34
  "{header}" => @opts.header,
33
35
  "{footer}" => "<div id='footer-content' style='display: none'>#{@opts.footer}</div>",
34
36
  "{extjs_path}" => @opts.extjs_path,
35
- "{welcome}" => @assets.welcome.to_html,
36
- "{categories}" => @assets.categories.to_html,
37
- "{guides}" => @assets.guides.to_html,
37
+ "{welcome}" => @assets.welcome.to_html("display:none"),
38
+ "{categories}" => @assets.categories.to_html("display:none"),
39
+ "{guides}" => @assets.guides.to_html("display:none"),
38
40
  "{head_html}" => @opts.head_html,
39
41
  "{body_html}" => @opts.body_html,
40
42
  })
@@ -47,10 +49,22 @@ module JsDuck
47
49
  })
48
50
  end
49
51
 
52
+ def create_index_template_html(in_file, out_file)
53
+ categories = @assets.categories.to_html
54
+ guides = @assets.guides.to_html
55
+
56
+ write_template(in_file, out_file, {
57
+ "{title}" => @opts.title,
58
+ "{header}" => @opts.header,
59
+ "{categories}" => categories ? "<h1>API Documentation</h1> #{categories}" : "",
60
+ "{guides}" => guides ? "<h1>Guides</h1> #{guides}" : "",
61
+ })
62
+ end
63
+
50
64
  # Opens in_file, replaces {keys} inside it, writes to out_file
51
65
  def write_template(in_file, out_file, replacements)
52
- Logger.instance.log("Writing", out_file)
53
- html = JsDuck::IO.read(in_file)
66
+ Logger.log("Writing", out_file)
67
+ html = Util::IO.read(in_file)
54
68
  html.gsub!(/\{\w+\}/) do |key|
55
69
  replacements[key] ? replacements[key] : key
56
70
  end
@@ -20,7 +20,7 @@ module JsDuck
20
20
  resolve(member, new_cfgs)
21
21
  end
22
22
  end
23
- move_cfgs(cls, new_cfgs)
23
+ move_cfgs(cls, new_cfgs) if new_cfgs.length > 0
24
24
  end
25
25
  end
26
26
 
@@ -52,12 +52,9 @@ module JsDuck
52
52
  def move_cfgs(cls, members)
53
53
  members.each do |m|
54
54
  m[:tagname] = :cfg
55
- cls[:members][:property].delete(m)
56
- cls[:members][:cfg] << m
57
55
  end
58
- # The members lookup table inside class is no more valid, so
59
- # reset it.
60
- cls.reset_members_lookup!
56
+ # Ask class to update its internal caches for these members
57
+ cls.update_members!(members)
61
58
  end
62
59
 
63
60
  # For auto-detected members/classes (which have @private == :inherit)
@@ -75,6 +72,7 @@ module JsDuck
75
72
  #
76
73
  # If the parent also has @inheritdoc, continues recursively.
77
74
  def find_parent(m)
75
+
78
76
  inherit = m[:inheritdoc] || {}
79
77
  if inherit[:cls]
80
78
  # @inheritdoc MyClass#member
@@ -120,7 +118,6 @@ module JsDuck
120
118
  end
121
119
  end
122
120
 
123
- #pp parent[:doc]
124
121
  return parent[:inheritdoc] ? find_parent(parent) : parent
125
122
  end
126
123
 
@@ -134,8 +131,8 @@ module JsDuck
134
131
  # Auto-detected properties can override either a property or a
135
132
  # config. So look for both types.
136
133
  if tagname == :property
137
- cfg = cls.get_members(name, :cfg, static || false)[0]
138
- prop = cls.get_members(name, :property, static || false)[0]
134
+ cfg = cls.find_members(:name => name, :tagname => :cfg, :static => static || false)[0]
135
+ prop = cls.find_members(:name => name, :tagname => :property, :static => static || false)[0]
139
136
 
140
137
  if cfg && prop
141
138
  prop
@@ -150,10 +147,10 @@ module JsDuck
150
147
  else
151
148
  # Unless the auto-detected member is detected as static,
152
149
  # look only at instance members.
153
- cls.get_members(name, tagname, static || false)[0]
150
+ cls.find_members(:name => name, :tagname => tagname, :static => static || false)[0]
154
151
  end
155
152
  else
156
- cls.get_members(name, tagname, static)[0]
153
+ cls.find_members(:name => name, :tagname => tagname, :static => static)[0]
157
154
  end
158
155
  end
159
156
 
@@ -185,7 +182,7 @@ module JsDuck
185
182
  i_member = item[:inheritdoc][:member]
186
183
 
187
184
  msg = "@inheritdoc #{item[:inheritdoc][:cls]}"+ (i_member ? "#" + i_member : "") + " - " + msg
188
- Logger.instance.warn(:inheritdoc, msg, context[:filename], context[:linenr])
185
+ Logger.warn(:inheritdoc, msg, context[:filename], context[:linenr])
189
186
 
190
187
  return nil
191
188
  end