jsduck 5.0.0.beta01 → 5.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -0
- data/README.md +6 -32
- data/Rakefile +5 -5
- data/bin/jsduck +0 -1
- data/js-classes/String.js +3 -5
- data/jsduck.gemspec +3 -2
- data/lib/jsduck/aggregator.rb +1 -3
- data/lib/jsduck/app.rb +2 -2
- data/lib/jsduck/categories/file.rb +0 -6
- data/lib/jsduck/class.rb +1 -2
- data/lib/jsduck/doc/parser.rb +12 -5
- data/lib/jsduck/doc/scanner.rb +6 -0
- data/lib/jsduck/doc/standard_tag_parser.rb +10 -5
- data/lib/jsduck/doc/subproperties.rb +9 -2
- data/lib/jsduck/docs_code_comparer.rb +20 -7
- data/lib/jsduck/exporter/app.rb +18 -13
- data/lib/jsduck/exporter/full.rb +18 -21
- data/lib/jsduck/format/doc.rb +0 -1
- data/lib/jsduck/format/html_stack.rb +1 -2
- data/lib/jsduck/format/subproperties.rb +2 -2
- data/lib/jsduck/inline/auto_link.rb +1 -1
- data/lib/jsduck/inline/img.rb +1 -1
- data/lib/jsduck/inline/link.rb +4 -6
- data/lib/jsduck/inline/video.rb +1 -2
- data/lib/jsduck/js/ast.rb +1 -1
- data/lib/jsduck/js/esprima.rb +24 -9
- data/lib/jsduck/logger.rb +50 -12
- data/lib/jsduck/members_index.rb +1 -2
- data/lib/jsduck/merger.rb +20 -2
- data/lib/jsduck/options.rb +125 -24
- data/lib/jsduck/process/accessors.rb +21 -8
- data/lib/jsduck/process/enums.rb +2 -3
- data/lib/jsduck/process/ext4_events.rb +2 -1
- data/lib/jsduck/process/global_members.rb +1 -2
- data/lib/jsduck/process/importer.rb +2 -6
- data/lib/jsduck/process/inherit_class.rb +58 -0
- data/lib/jsduck/process/inherit_doc.rb +6 -175
- data/lib/jsduck/process/inherit_members.rb +257 -0
- data/lib/jsduck/process/lint.rb +18 -7
- data/lib/jsduck/process/overrides.rb +1 -2
- data/lib/jsduck/render/class.rb +1 -1
- data/lib/jsduck/tag/alias.rb +2 -1
- data/lib/jsduck/tag/alternate_class_names.rb +1 -0
- data/lib/jsduck/tag/aside.rb +3 -3
- data/lib/jsduck/tag/author.rb +18 -3
- data/lib/jsduck/tag/autodetected.rb +21 -0
- data/lib/jsduck/tag/boolean_tag.rb +1 -1
- data/lib/jsduck/tag/cfg.rb +7 -3
- data/lib/jsduck/tag/class.rb +1 -1
- data/lib/jsduck/tag/class_list_tag.rb +1 -1
- data/lib/jsduck/tag/constructor.rb +1 -1
- data/lib/jsduck/tag/css_var.rb +1 -1
- data/lib/jsduck/tag/default.rb +1 -1
- data/lib/jsduck/tag/deprecated_tag.rb +1 -1
- data/lib/jsduck/tag/docauthor.rb +2 -0
- data/lib/jsduck/tag/enum.rb +2 -2
- data/lib/jsduck/tag/event.rb +1 -1
- data/lib/jsduck/tag/extends.rb +1 -1
- data/lib/jsduck/tag/ftype.rb +2 -1
- data/lib/jsduck/tag/inheritdoc.rb +1 -1
- data/lib/jsduck/tag/localdoc.rb +33 -0
- data/lib/jsduck/tag/markdown.rb +1 -1
- data/lib/jsduck/tag/member.rb +1 -1
- data/lib/jsduck/tag/method.rb +1 -1
- data/lib/jsduck/tag/mixins.rb +1 -0
- data/lib/jsduck/tag/override.rb +1 -1
- data/lib/jsduck/tag/param.rb +16 -5
- data/lib/jsduck/tag/preventable.rb +1 -1
- data/lib/jsduck/tag/property.rb +7 -3
- data/lib/jsduck/tag/ptype.rb +2 -1
- data/lib/jsduck/tag/requires.rb +1 -0
- data/lib/jsduck/tag/return.rb +2 -1
- data/lib/jsduck/tag/since.rb +1 -5
- data/lib/jsduck/tag/tag.rb +21 -12
- data/lib/jsduck/tag/throws.rb +2 -1
- data/lib/jsduck/tag/type.rb +2 -2
- data/lib/jsduck/tag/uses.rb +1 -0
- data/lib/jsduck/tag/xtype.rb +2 -1
- data/lib/jsduck/tag_loader.rb +26 -15
- data/lib/jsduck/tag_registry.rb +20 -11
- data/lib/jsduck/web/css.rb +22 -0
- data/lib/jsduck/web/data.rb +50 -0
- data/lib/jsduck/web/icons.rb +31 -0
- data/lib/jsduck/web/index_html.rb +88 -0
- data/lib/jsduck/web/search.rb +148 -0
- data/lib/jsduck/{source/writer.rb → web/source.rb} +2 -2
- data/lib/jsduck/web/template.rb +52 -0
- data/lib/jsduck/web/writer.rb +84 -0
- metadata +513 -488
- data/lib/jsduck/app_data.rb +0 -41
- data/lib/jsduck/icons.rb +0 -29
- data/lib/jsduck/index_html.rb +0 -84
- data/lib/jsduck/search_data.rb +0 -146
- data/lib/jsduck/template_dir.rb +0 -50
- data/lib/jsduck/web_writer.rb +0 -87
data/lib/jsduck/exporter/full.rb
CHANGED
@@ -6,40 +6,37 @@ module JsDuck
|
|
6
6
|
# Exporter for all the class docs.
|
7
7
|
class Full
|
8
8
|
def initialize(relations, opts={})
|
9
|
-
|
10
|
-
# opts parameter is here just for compatibility with other exporters
|
9
|
+
# parameters are just for compatibility with other exporters
|
11
10
|
end
|
12
11
|
|
13
|
-
# Returns
|
12
|
+
# Returns a hash of class data, with :members field expanded
|
13
|
+
# into list of all members (including those inherited from
|
14
|
+
# parents and mixins).
|
14
15
|
def export(cls)
|
15
16
|
# Make copy of the internal data structure of a class
|
16
17
|
# so our modifications on it will be safe.
|
17
18
|
h = cls.internal_doc.clone
|
18
19
|
|
19
|
-
h[:members] =
|
20
|
-
h[:statics] = {}
|
21
|
-
TagRegistry.member_type_names.each do |tagname|
|
22
|
-
h[:members][tagname] = export_members(cls, {:tagname => tagname, :static => false})
|
23
|
-
h[:statics][tagname] = export_members(cls, {:tagname => tagname, :static => true})
|
24
|
-
end
|
25
|
-
h[:component] = cls.inherits_from?("Ext.Component")
|
26
|
-
h[:superclasses] = cls.superclasses.collect {|c| c[:name] }
|
27
|
-
h[:subclasses] = @relations.subclasses(cls).collect {|c| c[:name] }.sort
|
28
|
-
h[:mixedInto] = @relations.mixed_into(cls).collect {|c| c[:name] }.sort
|
29
|
-
h[:alternateClassNames] = cls[:alternateClassNames].sort if cls[:alternateClassNames]
|
30
|
-
|
31
|
-
h[:mixins] = cls.deps(:mixins).collect {|c| c[:name] }.sort
|
32
|
-
h[:parentMixins] = cls.parent_deps(:mixins).collect {|c| c[:name] }.sort
|
33
|
-
h[:requires] = cls.deps(:requires).collect {|c| c[:name] }.sort
|
34
|
-
h[:uses] = cls.deps(:uses).collect {|c| c[:name] }.sort
|
20
|
+
h[:members] = export_members(cls)
|
35
21
|
|
36
22
|
h
|
37
23
|
end
|
38
24
|
|
39
25
|
private
|
40
26
|
|
41
|
-
#
|
42
|
-
def export_members(cls
|
27
|
+
# Generates flat list of all members
|
28
|
+
def export_members(cls)
|
29
|
+
groups = []
|
30
|
+
TagRegistry.member_type_names.each do |tagname|
|
31
|
+
groups << export_members_group(cls, {:tagname => tagname, :static => false})
|
32
|
+
groups << export_members_group(cls, {:tagname => tagname, :static => true})
|
33
|
+
end
|
34
|
+
groups.flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
# Looks up members of given type, and sorts them so that
|
38
|
+
# constructor method is first
|
39
|
+
def export_members_group(cls, cfg)
|
43
40
|
ms = cls.find_members(cfg)
|
44
41
|
ms.sort! {|a,b| a[:name] <=> b[:name] }
|
45
42
|
cfg[:tagname] == :method ? constructor_first(ms) : ms
|
data/lib/jsduck/format/doc.rb
CHANGED
@@ -78,9 +78,8 @@ module JsDuck
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def warn(msg, tags)
|
81
|
-
ctx = @doc_context
|
82
81
|
tag_list = tags.map {|tag| "<#{tag}>" }.join(", ")
|
83
|
-
Logger.warn(:html, "#{msg}: #{tag_list}",
|
82
|
+
Logger.warn(:html, "#{msg}: #{tag_list}", @doc_context)
|
84
83
|
end
|
85
84
|
|
86
85
|
def void?(tag)
|
@@ -50,9 +50,9 @@ module JsDuck
|
|
50
50
|
else
|
51
51
|
context = @formatter.doc_context
|
52
52
|
if tp.error == :syntax
|
53
|
-
Logger.warn(:type_syntax, "Incorrect type syntax #{type}", context
|
53
|
+
Logger.warn(:type_syntax, "Incorrect type syntax #{type}", context)
|
54
54
|
else
|
55
|
-
Logger.warn(:type_name, "Unknown type #{type}", context
|
55
|
+
Logger.warn(:type_name, "Unknown type #{type}", context)
|
56
56
|
end
|
57
57
|
Util::HTML.escape(type)
|
58
58
|
end
|
data/lib/jsduck/inline/img.rb
CHANGED
@@ -38,7 +38,7 @@ module JsDuck
|
|
38
38
|
def apply_tpl(url, alt_text)
|
39
39
|
img = @images.get(url)
|
40
40
|
if !img
|
41
|
-
Logger.warn(:image, "Image #{url} not found.", @doc_context
|
41
|
+
Logger.warn(:image, "Image #{url} not found.", @doc_context)
|
42
42
|
img = {}
|
43
43
|
end
|
44
44
|
|
data/lib/jsduck/inline/link.rb
CHANGED
@@ -62,15 +62,13 @@ module JsDuck
|
|
62
62
|
text = cls
|
63
63
|
end
|
64
64
|
|
65
|
-
file = @doc_context[:filename]
|
66
|
-
line = @doc_context[:linenr]
|
67
65
|
if !@relations[cls]
|
68
|
-
Logger.warn(:link, "#{full_link} links to non-existing class",
|
66
|
+
Logger.warn(:link, "#{full_link} links to non-existing class", @doc_context)
|
69
67
|
return text
|
70
68
|
elsif member
|
71
69
|
ms = @renderer.find_members(cls, {:name => member, :tagname => type, :static => static})
|
72
70
|
if ms.length == 0
|
73
|
-
Logger.warn(:link, "#{full_link} links to non-existing member",
|
71
|
+
Logger.warn(:link, "#{full_link} links to non-existing member", @doc_context)
|
74
72
|
return text
|
75
73
|
end
|
76
74
|
|
@@ -82,11 +80,11 @@ module JsDuck
|
|
82
80
|
instance_ms = ms.find_all {|m| !m[:static] }
|
83
81
|
if instance_ms.length > 1
|
84
82
|
alternatives = instance_ms.map {|m| "#{m[:tagname]} in #{m[:owner]}" }.join(", ")
|
85
|
-
Logger.warn(:link_ambiguous, "#{full_link} is ambiguous: "+alternatives,
|
83
|
+
Logger.warn(:link_ambiguous, "#{full_link} is ambiguous: "+alternatives, @doc_context)
|
86
84
|
elsif instance_ms.length == 0
|
87
85
|
static_ms = ms.find_all {|m| m[:static] }
|
88
86
|
alternatives = static_ms.map {|m| "static " + m[:tagname].to_s }.join(", ")
|
89
|
-
Logger.warn(:link_ambiguous, "#{full_link} is ambiguous: "+alternatives,
|
87
|
+
Logger.warn(:link_ambiguous, "#{full_link} is ambiguous: "+alternatives, @doc_context)
|
90
88
|
end
|
91
89
|
end
|
92
90
|
|
data/lib/jsduck/inline/video.rb
CHANGED
@@ -46,8 +46,7 @@ module JsDuck
|
|
46
46
|
# applies the video template of the specified type
|
47
47
|
def apply_tpl(type, url, alt_text)
|
48
48
|
unless @templates.has_key?(type)
|
49
|
-
|
50
|
-
Logger.warn(nil, "Unknown video type #{type}", ctx[:filename], ctx[:linenr])
|
49
|
+
Logger.warn(nil, "Unknown video type #{type}", @doc_context)
|
51
50
|
end
|
52
51
|
|
53
52
|
@templates[type].gsub(/(%\w)/) do
|
data/lib/jsduck/js/ast.rb
CHANGED
data/lib/jsduck/js/esprima.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
require '
|
1
|
+
require 'execjs'
|
2
2
|
require 'jsduck/util/json'
|
3
3
|
require 'jsduck/util/singleton'
|
4
4
|
|
5
5
|
module JsDuck
|
6
6
|
module Js
|
7
7
|
|
8
|
-
# Runs Esprima.js through
|
8
|
+
# Runs Esprima.js through JavaScript runtime selected by ExecJS.
|
9
|
+
# Normally this will be V8 engine within therubyracer gem, but when
|
10
|
+
# JSDuck is installed through some other means than rubygems, then
|
11
|
+
# one could use any of the runtimes supported by ExecJS. (NodeJS
|
12
|
+
# for example.)
|
9
13
|
#
|
10
14
|
# Initialized as singleton to avoid loading the esprima.js more
|
11
15
|
# than once - otherwise performace will severely suffer.
|
@@ -13,23 +17,34 @@ module JsDuck
|
|
13
17
|
include Util::Singleton
|
14
18
|
|
15
19
|
def initialize
|
16
|
-
|
17
|
-
esprima =
|
20
|
+
esprima_path = File.dirname(File.expand_path(__FILE__)) + "/esprima/esprima.js"
|
21
|
+
esprima = IO.read(esprima_path)
|
18
22
|
|
19
23
|
# Esprima attempts to assign to window.esprima, but our v8
|
20
24
|
# engine has no global window variable defined. So define our
|
21
25
|
# own and then grab esprima out from it again.
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
source = <<-EOJS
|
27
|
+
if (typeof window === "undefined") {
|
28
|
+
var window = {};
|
29
|
+
}
|
30
|
+
|
31
|
+
#{esprima}
|
32
|
+
|
33
|
+
var esprima = window.esprima;
|
34
|
+
|
35
|
+
function runEsprima(js) {
|
36
|
+
return JSON.stringify(esprima.parse(js, {comment: true, range: true, raw: true}));
|
37
|
+
}
|
38
|
+
EOJS
|
39
|
+
|
40
|
+
@context = ExecJS.compile(source)
|
25
41
|
end
|
26
42
|
|
27
43
|
# Parses JavaScript source code using Esprima.js
|
28
44
|
#
|
29
45
|
# Returns the resulting AST
|
30
46
|
def parse(input)
|
31
|
-
|
32
|
-
json = @v8.eval("JSON.stringify(esprima.parse(js, {comment: true, range: true, raw: true}))")
|
47
|
+
json = @context.call("runEsprima", input)
|
33
48
|
return Util::Json.parse(json, :max_nesting => false)
|
34
49
|
end
|
35
50
|
|
data/lib/jsduck/logger.rb
CHANGED
@@ -17,6 +17,8 @@ module JsDuck
|
|
17
17
|
[:inheritdoc, "@inheritdoc referring to unknown class or member"],
|
18
18
|
[:extend, "@extend/mixin/requires/uses referring to unknown class"],
|
19
19
|
[:tag, "Use of unsupported @tag"],
|
20
|
+
[:tag_repeated, "An @tag used multiple times, but only once allowed"],
|
21
|
+
[:tag_syntax, "@tag syntax error"],
|
20
22
|
[:link, "{@link} to unknown class or member"],
|
21
23
|
[:link_ambiguous, "{@link} is ambiguous"],
|
22
24
|
[:link_auto, "Auto-detected link to unknown class or member"],
|
@@ -24,7 +26,7 @@ module JsDuck
|
|
24
26
|
|
25
27
|
[:alt_name, "Name used as both classname and alternate classname"],
|
26
28
|
[:name_missing, "Member or parameter has no name"],
|
27
|
-
[:no_doc, "
|
29
|
+
[:no_doc, "Public class or member without documentation"],
|
28
30
|
[:dup_param, "Method has two parameters with the same name"],
|
29
31
|
[:dup_member, "Class has two members with the same name"],
|
30
32
|
[:req_after_opt, "Required parameter comes after optional"],
|
@@ -33,7 +35,7 @@ module JsDuck
|
|
33
35
|
[:sing_static, "Singleton class member marked as @static"],
|
34
36
|
[:type_syntax, "Syntax error in {type definition}"],
|
35
37
|
[:type_name, "Unknown type referenced in {type definition}"],
|
36
|
-
[:enum, "Enum with invalid values
|
38
|
+
[:enum, "Enum with invalid values or no values at all"],
|
37
39
|
|
38
40
|
[:image, "{@img} referring to missing file"],
|
39
41
|
[:image_unused, "An image exists in --images dir that's not used"],
|
@@ -50,7 +52,7 @@ module JsDuck
|
|
50
52
|
# When running JSDuck app, the Options class enables most warnings.
|
51
53
|
@warnings = {}
|
52
54
|
@warning_docs.each do |w|
|
53
|
-
@warnings[w[0]] = false
|
55
|
+
@warnings[w[0]] = {:enabled => false, :patterns => []}
|
54
56
|
end
|
55
57
|
|
56
58
|
@shown_warnings = {}
|
@@ -63,15 +65,26 @@ module JsDuck
|
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
66
|
-
#
|
67
|
-
# or all warnings when type == :all
|
68
|
-
|
68
|
+
# Enables or disables a particular warning
|
69
|
+
# or all warnings when type == :all.
|
70
|
+
# Additionally a filename pattern can be specified.
|
71
|
+
def set_warning(type, enabled, pattern=nil)
|
69
72
|
if type == :all
|
73
|
+
# When used with a pattern, only add the pattern to the rules
|
74
|
+
# where it can have an effect - otherwise we get a warning.
|
70
75
|
@warnings.each_key do |key|
|
71
|
-
@warnings[key]
|
76
|
+
set_warning(key, enabled, pattern) unless pattern && @warnings[key][:enabled] == enabled
|
72
77
|
end
|
73
78
|
elsif @warnings.has_key?(type)
|
74
|
-
|
79
|
+
if pattern
|
80
|
+
if @warnings[type][:enabled] == enabled
|
81
|
+
warn(nil, "Warning rule '#{enabled ? '+' : '-'}#{type}:#{pattern}' has no effect")
|
82
|
+
else
|
83
|
+
@warnings[type][:patterns] << Regexp.new(Regexp.escape(pattern))
|
84
|
+
end
|
85
|
+
else
|
86
|
+
@warnings[type] = {:enabled => enabled, :patterns => []}
|
87
|
+
end
|
75
88
|
else
|
76
89
|
warn(nil, "Warning of type '#{type}' doesn't exist")
|
77
90
|
end
|
@@ -79,7 +92,7 @@ module JsDuck
|
|
79
92
|
|
80
93
|
# get documentation for all warnings
|
81
94
|
def doc_warnings
|
82
|
-
@warning_docs.map {|w| " #{@warnings[w[0]] ? '+' : '-'}#{w[0]} - #{w[1]}" }
|
95
|
+
@warning_docs.map {|w| " #{@warnings[w[0]][:enabled] ? '+' : '-'}#{w[0]} - #{w[1]}" }
|
83
96
|
end
|
84
97
|
|
85
98
|
# Prints warning message.
|
@@ -93,21 +106,46 @@ module JsDuck
|
|
93
106
|
# warnings greatly also when run multiple processes.
|
94
107
|
#
|
95
108
|
# Optionally filename and line number will be inserted to message.
|
109
|
+
# These two last arguments can also be supplied as one hash of:
|
110
|
+
#
|
111
|
+
# {:filename => "foo.js", :linenr => 17}
|
112
|
+
#
|
96
113
|
def warn(type, msg, filename=nil, line=nil)
|
114
|
+
if filename.is_a?(Hash)
|
115
|
+
line = filename[:linenr]
|
116
|
+
filename = filename[:filename]
|
117
|
+
end
|
118
|
+
|
97
119
|
msg = paint(:yellow, "Warning: ") + format(filename, line) + " " + msg
|
98
120
|
|
99
|
-
if type
|
121
|
+
if warning_enabled?(type, filename)
|
100
122
|
if !@shown_warnings[msg]
|
101
123
|
$stderr.puts msg
|
102
124
|
@shown_warnings[msg] = true
|
103
125
|
end
|
104
|
-
elsif !@warnings.has_key?(type)
|
105
|
-
warn(nil, "Unknown warning type #{type}")
|
106
126
|
end
|
107
127
|
|
108
128
|
return false
|
109
129
|
end
|
110
130
|
|
131
|
+
# True when the warning is enabled for the given type and filename
|
132
|
+
# combination.
|
133
|
+
def warning_enabled?(type, filename)
|
134
|
+
if type == nil
|
135
|
+
true
|
136
|
+
elsif !@warnings.has_key?(type)
|
137
|
+
warn(nil, "Unknown warning type #{type}")
|
138
|
+
false
|
139
|
+
else
|
140
|
+
rule = @warnings[type]
|
141
|
+
if rule[:patterns].any? {|re| filename =~ re }
|
142
|
+
!rule[:enabled]
|
143
|
+
else
|
144
|
+
rule[:enabled]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
111
149
|
# Formats filename and line number for output
|
112
150
|
def format(filename=nil, line=nil)
|
113
151
|
out = ""
|
data/lib/jsduck/members_index.rb
CHANGED
@@ -97,9 +97,8 @@ module JsDuck
|
|
97
97
|
if hash1[name]
|
98
98
|
hash1.delete(name)
|
99
99
|
else
|
100
|
-
ctx = m[:files][0]
|
101
100
|
msg = "@hide used but #{m[:tagname]} #{m[:name]} not found in parent class"
|
102
|
-
Logger.warn(:hide, msg,
|
101
|
+
Logger.warn(:hide, msg, m[:files][0])
|
103
102
|
end
|
104
103
|
else
|
105
104
|
if hash1[name]
|
data/lib/jsduck/merger.rb
CHANGED
@@ -45,14 +45,32 @@ module JsDuck
|
|
45
45
|
def general_merge(h, docs, code)
|
46
46
|
# Merge in all items in docs that don't occour already in result.
|
47
47
|
docs.each_pair do |key, value|
|
48
|
-
h[key] = value unless h.has_key?(key)
|
48
|
+
h[key] = value unless h.has_key?(key) || Merger::explicit?(key)
|
49
49
|
end
|
50
50
|
# Then add all in the items from code not already in result.
|
51
51
|
code.each_pair do |key, value|
|
52
|
-
h[key] = value unless h.has_key?(key)
|
52
|
+
h[key] = value unless h.has_key?(key) || Merger::explicit?(key)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
# True when given key gets merged explicitly and should therefore
|
57
|
+
# be skipped when auto-merging.
|
58
|
+
def self.explicit?(key)
|
59
|
+
@explicit = explictly_merged_fields unless @explicit
|
60
|
+
@explicit[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Generates a lookup-hash of tagnames which are explicitly merged.
|
64
|
+
def self.explictly_merged_fields
|
65
|
+
mergers = {}
|
66
|
+
member_types = TagRegistry.member_type_names + [:class]
|
67
|
+
tags = member_types.map {|type| TagRegistry.mergers(type) }.flatten.uniq
|
68
|
+
tags.each do |tag|
|
69
|
+
mergers[tag.tagname] = true
|
70
|
+
end
|
71
|
+
mergers
|
72
|
+
end
|
73
|
+
|
56
74
|
end
|
57
75
|
|
58
76
|
end
|
data/lib/jsduck/options.rb
CHANGED
@@ -24,6 +24,8 @@ module JsDuck
|
|
24
24
|
attr_accessor :footer
|
25
25
|
attr_accessor :head_html
|
26
26
|
attr_accessor :body_html
|
27
|
+
attr_accessor :css
|
28
|
+
attr_accessor :message
|
27
29
|
attr_accessor :welcome
|
28
30
|
attr_accessor :guides
|
29
31
|
attr_accessor :videos
|
@@ -46,7 +48,6 @@ module JsDuck
|
|
46
48
|
attr_accessor :template_dir
|
47
49
|
attr_accessor :template_links
|
48
50
|
attr_accessor :extjs_path
|
49
|
-
attr_accessor :data_path
|
50
51
|
attr_accessor :local_storage_db
|
51
52
|
attr_accessor :touch_examples_ui
|
52
53
|
attr_accessor :ext_namespaces
|
@@ -91,14 +92,16 @@ module JsDuck
|
|
91
92
|
]
|
92
93
|
@ext4_events = nil
|
93
94
|
|
94
|
-
@version = "5.0.0.
|
95
|
+
@version = "5.0.0.beta2"
|
95
96
|
|
96
97
|
# Customizing output
|
97
98
|
@title = "Documentation - JSDuck"
|
98
99
|
@header = "<strong>Documentation</strong> JSDuck"
|
99
|
-
@footer = "Generated
|
100
|
+
@footer = format_footer("Generated on {DATE} by {JSDUCK} {VERSION}.")
|
100
101
|
@head_html = ""
|
101
102
|
@body_html = ""
|
103
|
+
@css = ""
|
104
|
+
@message = ""
|
102
105
|
@welcome = nil
|
103
106
|
@guides = nil
|
104
107
|
@videos = nil
|
@@ -125,7 +128,6 @@ module JsDuck
|
|
125
128
|
@template_dir = @root_dir + "/template-min"
|
126
129
|
@template_links = false
|
127
130
|
@extjs_path = "extjs/ext-all.js"
|
128
|
-
@data_path = nil # This gets assigned in JsDuck::WebWriter after writing the data file.
|
129
131
|
@local_storage_db = "docs"
|
130
132
|
@touch_examples_ui = false
|
131
133
|
@imports = []
|
@@ -138,6 +140,8 @@ module JsDuck
|
|
138
140
|
Logger.set_warning(:all, true)
|
139
141
|
Logger.set_warning(:link_auto, false)
|
140
142
|
Logger.set_warning(:param_count, false)
|
143
|
+
|
144
|
+
@optparser = create_option_parser
|
141
145
|
end
|
142
146
|
|
143
147
|
# Make options object behave like hash.
|
@@ -150,16 +154,25 @@ module JsDuck
|
|
150
154
|
end
|
151
155
|
|
152
156
|
def parse!(argv)
|
153
|
-
|
154
|
-
|
155
|
-
end
|
157
|
+
parse_options(argv)
|
158
|
+
auto_detect_config_file
|
156
159
|
validate
|
157
160
|
|
158
|
-
@custom_tag_paths.
|
161
|
+
if @custom_tag_paths.length > 0
|
162
|
+
TagRegistry.reconfigure(@custom_tag_paths)
|
163
|
+
else
|
164
|
+
# Ensure the TagRegistry get instantiated just once.
|
165
|
+
# Otherwise the parallel processing causes multiple requests
|
166
|
+
# to initialize the TagRegistry, resulting in loading the Tag
|
167
|
+
# definitions multiple times.
|
168
|
+
TagRegistry.instance
|
169
|
+
end
|
159
170
|
end
|
160
171
|
|
172
|
+
private
|
173
|
+
|
161
174
|
def create_option_parser
|
162
|
-
|
175
|
+
return JsDuck::OptionParser.new do | opts |
|
163
176
|
opts.banner = "Usage: jsduck [options] files/dirs..."
|
164
177
|
opts.separator ""
|
165
178
|
opts.separator "For example:"
|
@@ -227,6 +240,9 @@ module JsDuck
|
|
227
240
|
"",
|
228
241
|
"An alternative to listing all options on command line.",
|
229
242
|
"",
|
243
|
+
"When the current directory contains jsduck.json file",
|
244
|
+
"then options are automatically read from there.",
|
245
|
+
"",
|
230
246
|
"See also: https://github.com/senchalabs/jsduck/wiki/Config-file") do |path|
|
231
247
|
path = canonical(path)
|
232
248
|
if File.exists?(path)
|
@@ -238,7 +254,7 @@ module JsDuck
|
|
238
254
|
# treat paths inside JSON config relative to the location of
|
239
255
|
# config file. When done, switch back to current working dir.
|
240
256
|
@working_dir = File.dirname(path)
|
241
|
-
|
257
|
+
parse_options(config)
|
242
258
|
@working_dir = nil
|
243
259
|
end
|
244
260
|
|
@@ -265,11 +281,14 @@ module JsDuck
|
|
265
281
|
opts.on('--footer=TEXT',
|
266
282
|
"Custom footer text for the documentation.",
|
267
283
|
"",
|
268
|
-
"
|
284
|
+
"The text can contain various placeholders:",
|
285
|
+
"",
|
286
|
+
" {DATE} - current date and time.",
|
287
|
+
" {JSDUCK} - link to JSDuck homepage.",
|
288
|
+
" {VERSION} - JSDuck version number.",
|
269
289
|
"",
|
270
|
-
"'{
|
271
|
-
|
272
|
-
@footer = text.gsub(/\{VERSION\}/, @version)
|
290
|
+
"Defaults to: 'Generated on {DATE} by {JSDUCK} {VERSION}.'") do |text|
|
291
|
+
@footer = format_footer(text)
|
273
292
|
end
|
274
293
|
|
275
294
|
opts.on('--head-html=HTML',
|
@@ -277,9 +296,12 @@ module JsDuck
|
|
277
296
|
"",
|
278
297
|
"Useful for adding extra <style> and other tags.",
|
279
298
|
"",
|
299
|
+
"Also a name of an HTML file can be passed.",
|
300
|
+
"Then the contents of that file will be read in.",
|
301
|
+
"",
|
280
302
|
"This option can be used repeatedly to append several",
|
281
303
|
"things to the header.") do |html|
|
282
|
-
@head_html += html
|
304
|
+
@head_html += maybe_file(html)
|
283
305
|
end
|
284
306
|
|
285
307
|
opts.on('--body-html=HTML',
|
@@ -287,9 +309,32 @@ module JsDuck
|
|
287
309
|
"",
|
288
310
|
"Useful for adding extra markup to the page.",
|
289
311
|
"",
|
312
|
+
"Also a name of an HTML file can be passed.",
|
313
|
+
"Then the contents of that file will be read in.",
|
314
|
+
"",
|
290
315
|
"This option can be used repeatedly to append several",
|
291
316
|
"things to the body.") do |html|
|
292
|
-
@body_html += html
|
317
|
+
@body_html += maybe_file(html)
|
318
|
+
end
|
319
|
+
|
320
|
+
opts.on('--css=CSS',
|
321
|
+
"Extra CSS rules to include to the page.",
|
322
|
+
"",
|
323
|
+
"Also a name of a CSS file can be passed.",
|
324
|
+
"Then the contents of that file will be read in.",
|
325
|
+
"",
|
326
|
+
"This option can be used repeatedly to append multiple",
|
327
|
+
"chunks of CSS.") do |css|
|
328
|
+
@css += maybe_file(css)
|
329
|
+
end
|
330
|
+
|
331
|
+
opts.on('--message=HTML',
|
332
|
+
"(Warning) message to show prominently.",
|
333
|
+
"",
|
334
|
+
"Useful for warning users that they are viewing an old",
|
335
|
+
"version of the docs, and prividing a link to the new",
|
336
|
+
"version.") do |html|
|
337
|
+
@message += html
|
293
338
|
end
|
294
339
|
|
295
340
|
opts.on('--welcome=PATH',
|
@@ -546,7 +591,7 @@ module JsDuck
|
|
546
591
|
@touch_examples_ui = true
|
547
592
|
end
|
548
593
|
|
549
|
-
opts.on('--ignore-html=
|
594
|
+
opts.on('--ignore-html=TAG1,TAG2', Array,
|
550
595
|
"Ignore a particular unclosed HTML tag.",
|
551
596
|
"",
|
552
597
|
"Normally all tags like <foo> that aren't followed at some",
|
@@ -557,8 +602,10 @@ module JsDuck
|
|
557
602
|
"",
|
558
603
|
"Useful for ignoring the ExtJS preprocessor directives",
|
559
604
|
"<locale> and <debug> which would otherwise be reported",
|
560
|
-
"as unclosed tags.") do |
|
561
|
-
|
605
|
+
"as unclosed tags.") do |tags|
|
606
|
+
tags.each do |tag|
|
607
|
+
@ignore_html[tag] = true
|
608
|
+
end
|
562
609
|
end
|
563
610
|
|
564
611
|
opts.separator ""
|
@@ -568,24 +615,40 @@ module JsDuck
|
|
568
615
|
opts.on('-v', '--verbose',
|
569
616
|
"Turns on excessive logging.",
|
570
617
|
"",
|
571
|
-
"Log messages are
|
618
|
+
"Log messages are written to STDERR.") do
|
572
619
|
Logger.verbose = true
|
573
620
|
end
|
574
621
|
|
575
622
|
opts.on('--warnings=+A,-B,+C', Array,
|
576
623
|
"Turns warnings selectively on/off.",
|
577
624
|
"",
|
578
|
-
" +all - to turn on all warnings",
|
625
|
+
" +all - to turn on all warnings.",
|
626
|
+
" -all - to turn off all warnings.",
|
627
|
+
"",
|
628
|
+
"Additionally a pattern can be specified to only apply the",
|
629
|
+
"setting for a particular set of files. For example to turn",
|
630
|
+
"off all warnings related to chart classes:",
|
631
|
+
"",
|
632
|
+
" -all:extjs/src/chart",
|
633
|
+
"",
|
634
|
+
"Note, that the order of the rules matters. When you first",
|
635
|
+
"say +link and then -all, the result will be that all warnings",
|
636
|
+
"get disabled.",
|
637
|
+
"",
|
638
|
+
"Currently one can't mix disabling and enabling file patterns.",
|
639
|
+
"For example --warnings=-link,+link:/src,-link:/src/ux will",
|
640
|
+
"ignore the last rule about /src/ux.",
|
579
641
|
"",
|
580
642
|
"List of all available warning types:",
|
581
643
|
"(Those with '+' in front of them default to on)",
|
582
644
|
"",
|
583
645
|
*Logger.doc_warnings) do |warnings|
|
584
646
|
warnings.each do |op|
|
585
|
-
if op =~ /^([-+]?)(.*)
|
647
|
+
if op =~ /^([-+]?)(\w+)(?::(.*))?$/
|
586
648
|
enable = !($1 == "-")
|
587
649
|
name = $2.to_sym
|
588
|
-
|
650
|
+
path = $3
|
651
|
+
Logger.set_warning(name, enable, path)
|
589
652
|
end
|
590
653
|
end
|
591
654
|
end
|
@@ -628,6 +691,14 @@ module JsDuck
|
|
628
691
|
@template_links = true
|
629
692
|
end
|
630
693
|
|
694
|
+
opts.on('-d', '--debug',
|
695
|
+
"Same as --template=template --template-links.",
|
696
|
+
"",
|
697
|
+
"Useful shorthand during development.") do
|
698
|
+
@template_dir = canonical("template")
|
699
|
+
@template_links = true
|
700
|
+
end
|
701
|
+
|
631
702
|
opts.on('--extjs-path=PATH',
|
632
703
|
"Path for main ExtJS JavaScript file.",
|
633
704
|
"",
|
@@ -669,8 +740,20 @@ module JsDuck
|
|
669
740
|
exit
|
670
741
|
end
|
671
742
|
end
|
743
|
+
end
|
744
|
+
|
745
|
+
# Parses the given command line options
|
746
|
+
# (could have also been read from config file)
|
747
|
+
def parse_options(options)
|
748
|
+
@optparser.parse!(options).each {|fname| read_filenames(canonical(fname)) }
|
749
|
+
end
|
672
750
|
|
673
|
-
|
751
|
+
# Reads jsduck.json file in current directory
|
752
|
+
def auto_detect_config_file
|
753
|
+
fname = Dir.pwd + "/jsduck.json"
|
754
|
+
if File.exists?(fname)
|
755
|
+
parse_options(read_json_config(fname))
|
756
|
+
end
|
674
757
|
end
|
675
758
|
|
676
759
|
# Reads JSON configuration from file and returns an array of
|
@@ -724,6 +807,17 @@ module JsDuck
|
|
724
807
|
end.flatten
|
725
808
|
end
|
726
809
|
|
810
|
+
# When given string is a file, returns the contents of the file.
|
811
|
+
# Otherwise returns the string unchanged.
|
812
|
+
def maybe_file(str)
|
813
|
+
path = canonical(str)
|
814
|
+
if File.exists?(path)
|
815
|
+
Util::IO.read(path)
|
816
|
+
else
|
817
|
+
str
|
818
|
+
end
|
819
|
+
end
|
820
|
+
|
727
821
|
# Converts relative path to full path
|
728
822
|
#
|
729
823
|
# Especially important for running on Windows where C:\foo\bar
|
@@ -733,6 +827,13 @@ module JsDuck
|
|
733
827
|
File.expand_path(path, @working_dir)
|
734
828
|
end
|
735
829
|
|
830
|
+
# Replace special placeholders in footer text
|
831
|
+
def format_footer(text)
|
832
|
+
jsduck = "<a href='https://github.com/senchalabs/jsduck'>JSDuck</a>"
|
833
|
+
date = Time.new.strftime('%a %d %b %Y %H:%M:%S')
|
834
|
+
text.gsub(/\{VERSION\}/, @version).gsub(/\{JSDUCK\}/, jsduck).gsub(/\{DATE\}/, date)
|
835
|
+
end
|
836
|
+
|
736
837
|
# Runs checks on the options
|
737
838
|
def validate
|
738
839
|
if @input_files.length == 0 && !@welcome && !@guides && !@videos && !@examples
|