jsduck 4.0.1 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
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