jsduck 3.0.pre → 3.0.pre2
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.
- data/README.md +21 -229
- data/Rakefile +31 -17
- data/bin/jsduck +1 -0
- data/js-classes/Array.js +561 -0
- data/js-classes/Boolean.js +110 -0
- data/js-classes/Date.js +999 -0
- data/js-classes/Function.js +256 -0
- data/js-classes/Number.js +308 -0
- data/js-classes/Object.js +404 -0
- data/js-classes/RegExp.js +415 -0
- data/js-classes/String.js +1034 -0
- data/jsduck.gemspec +2 -2
- data/lib/jsduck/accessors.rb +71 -0
- data/lib/jsduck/aggregator.rb +14 -2
- data/lib/jsduck/app.rb +6 -5
- data/lib/jsduck/class_formatter.rb +12 -8
- data/lib/jsduck/css_parser.rb +2 -2
- data/lib/jsduck/doc_formatter.rb +2 -2
- data/lib/jsduck/doc_parser.rb +32 -25
- data/lib/jsduck/exporter.rb +1 -1
- data/lib/jsduck/guides.rb +11 -2
- data/lib/jsduck/js_parser.rb +30 -8
- data/lib/jsduck/merger.rb +31 -16
- data/lib/jsduck/options.rb +93 -15
- data/lib/jsduck/renderer.rb +40 -3
- data/lib/jsduck/search_data.rb +8 -5
- data/lib/jsduck/source_file.rb +5 -4
- data/lib/jsduck/type_parser.rb +7 -6
- metadata +17 -5
- data/example.js +0 -144
data/lib/jsduck/merger.rb
CHANGED
@@ -113,8 +113,7 @@ module JsDuck
|
|
113
113
|
:mixins => detect_list(:mixins, doc_map, code),
|
114
114
|
:alternateClassNames => detect_list(:alternateClassNames, doc_map, code),
|
115
115
|
:xtypes => detect_xtypes(doc_map, code),
|
116
|
-
:
|
117
|
-
:docauthor => detect_docauthor(doc_map),
|
116
|
+
:meta => detect_meta(doc_map),
|
118
117
|
:singleton => detect_singleton(doc_map, code),
|
119
118
|
:requires => detect_list(:requires, doc_map, code),
|
120
119
|
:uses => detect_list(:uses, doc_map, code),
|
@@ -144,6 +143,7 @@ module JsDuck
|
|
144
143
|
:doc => detect_doc(docs),
|
145
144
|
:params => detect_params(docs, code),
|
146
145
|
:return => detect_return(doc_map, name == "constructor" ? "Object" : "undefined"),
|
146
|
+
:template => !!doc_map[:template],
|
147
147
|
}, doc_map)
|
148
148
|
end
|
149
149
|
|
@@ -166,9 +166,10 @@ module JsDuck
|
|
166
166
|
:owner => detect_owner(doc_map) || owner,
|
167
167
|
:type => detect_type(:cfg, doc_map, code),
|
168
168
|
:doc => detect_doc(docs),
|
169
|
-
:
|
169
|
+
:required => detect_required(:cfg, doc_map),
|
170
170
|
:default => detect_default(:cfg, doc_map, code),
|
171
171
|
:properties => detect_subproperties(docs, :cfg),
|
172
|
+
:accessor => !!doc_map[:accessor],
|
172
173
|
}, doc_map)
|
173
174
|
end
|
174
175
|
|
@@ -208,7 +209,7 @@ module JsDuck
|
|
208
209
|
|
209
210
|
# Detects properties common for each doc-object and adds them
|
210
211
|
def add_shared(hash, doc_map)
|
211
|
-
|
212
|
+
hash.merge!({
|
212
213
|
:private => !!doc_map[:private],
|
213
214
|
:protected => !!doc_map[:protected],
|
214
215
|
:static => !!doc_map[:static],
|
@@ -216,6 +217,12 @@ module JsDuck
|
|
216
217
|
:deprecated => detect_deprecated(doc_map),
|
217
218
|
:alias => doc_map[:alias] ? doc_map[:alias].first : nil,
|
218
219
|
})
|
220
|
+
hash[:id] = create_member_id(hash)
|
221
|
+
return hash
|
222
|
+
end
|
223
|
+
|
224
|
+
def create_member_id(m)
|
225
|
+
"#{m[:static] ? 'static-' : ''}#{m[:tagname]}-#{m[:name]}"
|
219
226
|
end
|
220
227
|
|
221
228
|
def detect_name(tagname, doc_map, code, name_type = :last_name)
|
@@ -265,7 +272,9 @@ module JsDuck
|
|
265
272
|
|
266
273
|
def detect_extends(doc_map, code)
|
267
274
|
if doc_map[:extends]
|
268
|
-
doc_map[:extends].first[:extends]
|
275
|
+
cls = doc_map[:extends].first[:extends]
|
276
|
+
# Ignore extending of the Object class
|
277
|
+
cls == "Object" ? nil : cls
|
269
278
|
elsif code[:type] == :assignment && code[:right] && code[:right][:type] == :ext_extend
|
270
279
|
code[:right][:extend].join(".")
|
271
280
|
elsif code[:type] == :ext_define
|
@@ -291,9 +300,9 @@ module JsDuck
|
|
291
300
|
return explicit_name == "" || explicit_name == implicit_name
|
292
301
|
end
|
293
302
|
|
294
|
-
def
|
303
|
+
def detect_required(tagname, doc_map)
|
295
304
|
main_tag = doc_map[tagname] ? doc_map[tagname].first : {}
|
296
|
-
return main_tag[:optional]
|
305
|
+
return main_tag[:optional] == false
|
297
306
|
end
|
298
307
|
|
299
308
|
# for detecting mixins and alternateClassNames
|
@@ -309,20 +318,26 @@ module JsDuck
|
|
309
318
|
|
310
319
|
def detect_xtypes(doc_map, code)
|
311
320
|
if doc_map[:xtype]
|
312
|
-
doc_map[:xtype].map {|tag| tag[:name] }
|
321
|
+
{"widget" => doc_map[:xtype].map {|tag| tag[:name] } }
|
313
322
|
elsif code[:alias]
|
314
|
-
|
323
|
+
xtypes = {}
|
324
|
+
code[:alias].each do |a|
|
325
|
+
if a =~ /^(\w+)\.(\w+)$/
|
326
|
+
if xtypes[$1]
|
327
|
+
xtypes[$1] << $2
|
328
|
+
else
|
329
|
+
xtypes[$1] = [$2]
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
xtypes
|
315
334
|
else
|
316
|
-
|
335
|
+
{}
|
317
336
|
end
|
318
337
|
end
|
319
338
|
|
320
|
-
def
|
321
|
-
doc_map[:
|
322
|
-
end
|
323
|
-
|
324
|
-
def detect_docauthor(doc_map)
|
325
|
-
doc_map[:docauthor] ? doc_map[:docauthor].first[:name] : nil
|
339
|
+
def detect_meta(doc_map)
|
340
|
+
doc_map[:meta] ? doc_map[:meta].map {|tag| {:name => tag[:name], :content => tag[:content]} } : []
|
326
341
|
end
|
327
342
|
|
328
343
|
def detect_deprecated(doc_map)
|
data/lib/jsduck/options.rb
CHANGED
@@ -9,6 +9,7 @@ module JsDuck
|
|
9
9
|
attr_accessor :output_dir
|
10
10
|
attr_accessor :ignore_global
|
11
11
|
attr_accessor :external_classes
|
12
|
+
attr_accessor :meta_tags
|
12
13
|
attr_accessor :warnings
|
13
14
|
attr_accessor :verbose
|
14
15
|
|
@@ -36,6 +37,7 @@ module JsDuck
|
|
36
37
|
attr_accessor :template_links
|
37
38
|
attr_accessor :extjs_path
|
38
39
|
attr_accessor :local_storage_db
|
40
|
+
attr_accessor :ext_namespaces
|
39
41
|
|
40
42
|
def initialize
|
41
43
|
@input_files = []
|
@@ -63,15 +65,19 @@ module JsDuck
|
|
63
65
|
"CSSStyleRule",
|
64
66
|
"Event",
|
65
67
|
]
|
68
|
+
@meta_tags = [
|
69
|
+
{:name => "author", :title => "Author", :strip => / *<.*?> */},
|
70
|
+
{:name => "docauthor", :title => "Documentation author", :strip => / *<.*?> */},
|
71
|
+
]
|
66
72
|
|
67
73
|
@warnings = true
|
68
74
|
@verbose = false
|
69
|
-
@version = "3.0.
|
75
|
+
@version = "3.0.pre2"
|
70
76
|
|
71
77
|
# Customizing output
|
72
78
|
@title = "Sencha Docs - Ext JS"
|
73
79
|
@header = "<strong>Sencha Docs</strong> Ext JS"
|
74
|
-
@footer =
|
80
|
+
@footer = "Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> #{@version}."
|
75
81
|
@head_html = ""
|
76
82
|
@body_html = ""
|
77
83
|
@welcome = nil
|
@@ -90,10 +96,18 @@ module JsDuck
|
|
90
96
|
|
91
97
|
# Debugging
|
92
98
|
@processes = nil
|
93
|
-
@
|
99
|
+
@root_dir = File.dirname(File.dirname(File.dirname(__FILE__)))
|
100
|
+
@template_dir = @root_dir + "/template-min"
|
94
101
|
@template_links = false
|
95
102
|
@extjs_path = "extjs/ext-all.js"
|
96
103
|
@local_storage_db = "docs"
|
104
|
+
@ext_namespaces = ["Ext"]
|
105
|
+
end
|
106
|
+
|
107
|
+
# Make options object behave like hash.
|
108
|
+
# This allows us to substitute it with hash in unit tests.
|
109
|
+
def [](key)
|
110
|
+
send(key)
|
97
111
|
end
|
98
112
|
|
99
113
|
def parse!(argv)
|
@@ -107,8 +121,8 @@ module JsDuck
|
|
107
121
|
|
108
122
|
opts.on('-o', '--output=PATH',
|
109
123
|
"Directory to output all this amazing documentation.",
|
110
|
-
"This option MUST be specified.", " ") do |path|
|
111
|
-
@output_dir = path
|
124
|
+
"This option MUST be specified (unless --stdout).", " ") do |path|
|
125
|
+
@output_dir = canonical(path)
|
112
126
|
end
|
113
127
|
|
114
128
|
opts.on('--ignore-global', "Turns off the creation of global class.", " ") do
|
@@ -122,6 +136,20 @@ module JsDuck
|
|
122
136
|
@external_classes += classes
|
123
137
|
end
|
124
138
|
|
139
|
+
opts.on('--builtin-classes',
|
140
|
+
"Includes docs for JavaScript builtin classes.", " ") do
|
141
|
+
read_filenames(@root_dir + "/js-classes")
|
142
|
+
end
|
143
|
+
|
144
|
+
opts.on('--meta-tags @name=Title,...', Array,
|
145
|
+
"Defines custom meta-data tags in addition to",
|
146
|
+
"@author and @docauthor. Experimantal!", " ") do |tags|
|
147
|
+
tags.each do |t|
|
148
|
+
t = t.split(/=/)
|
149
|
+
@meta_tags << {:name => t[0].sub(/^@/, ""), :title => t[1]}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
125
153
|
opts.on('--no-warnings', "Turns off warnings.", " ") do
|
126
154
|
@warnings = false
|
127
155
|
end
|
@@ -156,7 +184,7 @@ module JsDuck
|
|
156
184
|
|
157
185
|
opts.on('--welcome=PATH',
|
158
186
|
"Path to HTML file with content for welcome page.", " ") do |path|
|
159
|
-
@welcome = path
|
187
|
+
@welcome = canonical(path)
|
160
188
|
end
|
161
189
|
|
162
190
|
opts.on('--guides=PATH',
|
@@ -164,26 +192,26 @@ module JsDuck
|
|
164
192
|
"should be in a dir containing the actual guides.",
|
165
193
|
"A guide is a dir containing README.md, icon.png,",
|
166
194
|
"and other images referenced by the README.md file.", " ") do |path|
|
167
|
-
@guides = path
|
195
|
+
@guides = canonical(path)
|
168
196
|
end
|
169
197
|
|
170
198
|
opts.on('--videos=PATH',
|
171
199
|
"Path to JSON file describing the videos.", " ") do |path|
|
172
|
-
@videos = path
|
200
|
+
@videos = canonical(path)
|
173
201
|
end
|
174
202
|
|
175
203
|
opts.on('--examples=PATH',
|
176
204
|
"Path JSON file describing the examples.", " ") do |path|
|
177
|
-
@examples = path
|
205
|
+
@examples = canonical(path)
|
178
206
|
end
|
179
207
|
|
180
208
|
opts.on('--categories=PATH',
|
181
209
|
"Path to JSON file which defines categories for classes.", " ") do |path|
|
182
|
-
@categories_path = path
|
210
|
+
@categories_path = canonical(path)
|
183
211
|
end
|
184
212
|
|
185
213
|
opts.on('--inline-examples=PATH', "Path to inline examples directory.", " ") do |path|
|
186
|
-
@inline_examples_dir = path
|
214
|
+
@inline_examples_dir = canonical(path)
|
187
215
|
end
|
188
216
|
|
189
217
|
opts.on('--pretty-json', "Turn on pretty-printing of JSON.", " ") do
|
@@ -237,7 +265,7 @@ module JsDuck
|
|
237
265
|
|
238
266
|
opts.on('--template=PATH',
|
239
267
|
"Directory containing doc-browser UI template.", " ") do |path|
|
240
|
-
@template_dir = path
|
268
|
+
@template_dir = canonical(path)
|
241
269
|
end
|
242
270
|
|
243
271
|
opts.on('--template-links',
|
@@ -250,7 +278,7 @@ module JsDuck
|
|
250
278
|
opts.on('--extjs-path=PATH',
|
251
279
|
"Path for main ExtJS JavaScript file. Useful for specifying",
|
252
280
|
"something different than extjs/ext.js", " ") do |path|
|
253
|
-
@extjs_path = path
|
281
|
+
@extjs_path = path # NB! must be relative path
|
254
282
|
end
|
255
283
|
|
256
284
|
opts.on('--local-storage-db=NAME',
|
@@ -259,8 +287,49 @@ module JsDuck
|
|
259
287
|
@local_storage_db = name
|
260
288
|
end
|
261
289
|
|
262
|
-
opts.on('-
|
263
|
-
|
290
|
+
opts.on('--ext-namespaces=Ext,Foo', Array,
|
291
|
+
"Namespace(s) of ExtJS. Defaults to 'Ext'.", " ") do |ns|
|
292
|
+
@ext_namespaces = ns
|
293
|
+
end
|
294
|
+
|
295
|
+
opts.on('-h', '--help[=full]',
|
296
|
+
"Short help or --help=full for all available options.", " ") do |v|
|
297
|
+
if v == 'full'
|
298
|
+
puts opts
|
299
|
+
else
|
300
|
+
puts opts.banner
|
301
|
+
puts "For example:"
|
302
|
+
puts
|
303
|
+
puts " # Documentation for builtin JavaScript classes like Array and String"
|
304
|
+
puts " jsduck --output output/dir --builtin-classes"
|
305
|
+
puts
|
306
|
+
puts " # Documentation for your own JavaScript"
|
307
|
+
puts " jsduck --output output/dir input-file.js some/input/dir"
|
308
|
+
puts
|
309
|
+
puts "The main options:"
|
310
|
+
puts
|
311
|
+
|
312
|
+
show_help = false
|
313
|
+
main_opts = [
|
314
|
+
/--output/,
|
315
|
+
/--builtin-classes/,
|
316
|
+
/--no-warnings/,
|
317
|
+
/--verbose/,
|
318
|
+
/--help/,
|
319
|
+
/--version/,
|
320
|
+
]
|
321
|
+
opts.summarize([], opts.summary_width) do |helpline|
|
322
|
+
if main_opts.any? {|re| helpline =~ re }
|
323
|
+
puts helpline
|
324
|
+
show_help = true
|
325
|
+
elsif helpline =~ /^\s*$/ && show_help == true
|
326
|
+
puts helpline
|
327
|
+
show_help = false
|
328
|
+
elsif show_help == true
|
329
|
+
puts helpline
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
264
333
|
exit
|
265
334
|
end
|
266
335
|
|
@@ -284,6 +353,15 @@ module JsDuck
|
|
284
353
|
end
|
285
354
|
end
|
286
355
|
|
356
|
+
# Converts relative path to full path
|
357
|
+
#
|
358
|
+
# Especially important for running on Windows where C:\foo\bar
|
359
|
+
# pathnames are converted to C:/foo/bar which ruby can work on
|
360
|
+
# more easily.
|
361
|
+
def canonical(path)
|
362
|
+
File.expand_path(path)
|
363
|
+
end
|
364
|
+
|
287
365
|
# Runs checks on the options
|
288
366
|
def validate
|
289
367
|
if @input_files.length == 0
|
data/lib/jsduck/renderer.rb
CHANGED
@@ -5,6 +5,10 @@ module JsDuck
|
|
5
5
|
# Ruby-side implementation of class docs Renderer.
|
6
6
|
# Uses PhantomJS to run Docs.Renderer JavaScript.
|
7
7
|
class Renderer
|
8
|
+
def initialize(options={})
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
8
12
|
def render(cls)
|
9
13
|
@cls = cls
|
10
14
|
|
@@ -14,6 +18,7 @@ module JsDuck
|
|
14
18
|
"<div class='doc-contents'>",
|
15
19
|
render_private_class_notice,
|
16
20
|
@cls[:doc],
|
21
|
+
render_meta_data,
|
17
22
|
"</div>",
|
18
23
|
"<div class='members'>",
|
19
24
|
render_member_sections,
|
@@ -31,6 +36,25 @@ module JsDuck
|
|
31
36
|
]
|
32
37
|
end
|
33
38
|
|
39
|
+
def render_meta_data
|
40
|
+
return if !@cls[:meta] || @cls[:meta].length == 0
|
41
|
+
|
42
|
+
html = ["<ul class='meta-data'>"]
|
43
|
+
|
44
|
+
@options[:meta_tags].each do |meta|
|
45
|
+
title = meta[:title]
|
46
|
+
items = @cls[:meta].find_all {|m| m[:name] == meta[:name]}.map {|m| m[:content] }
|
47
|
+
content = meta[:strip] ? items.map {|m| m.gsub(meta[:strip], "") } : items
|
48
|
+
if items.length > 0
|
49
|
+
html << "<li><strong>#{CGI.escapeHTML(title)}:</strong> #{CGI.escapeHTML(content.join(', '))}</li>"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
html << "</ul>"
|
54
|
+
|
55
|
+
html
|
56
|
+
end
|
57
|
+
|
34
58
|
def render_hierarchy
|
35
59
|
has_parents = @cls[:extends] && @cls[:extends] != "Object"
|
36
60
|
has_alt_names = @cls[:alternateClassNames].length > 0
|
@@ -144,7 +168,7 @@ module JsDuck
|
|
144
168
|
inherited = owner == @cls[:name] ? "not-inherited" : "inherited"
|
145
169
|
|
146
170
|
return [
|
147
|
-
"<div id='#{m[:
|
171
|
+
"<div id='#{m[:id]}' class='member #{first_child} #{inherited}'>",
|
148
172
|
# leftmost column: expand button
|
149
173
|
"<a href='#' class='side #{expandable}'>",
|
150
174
|
"<span> </span>",
|
@@ -201,11 +225,14 @@ module JsDuck
|
|
201
225
|
if m[:deprecated]
|
202
226
|
after += "<strong class='deprecated-signature'>deprecated</strong>"
|
203
227
|
end
|
204
|
-
if m[:
|
228
|
+
if m[:required]
|
205
229
|
after += "<strong class='required-signature'>required</strong>"
|
206
230
|
end
|
231
|
+
if m[:template]
|
232
|
+
after += "<strong class='template-signature'>template</strong>"
|
233
|
+
end
|
207
234
|
|
208
|
-
uri = "#!/api/#{m[:owner]}-#{m[:
|
235
|
+
uri = "#!/api/#{m[:owner]}-#{m[:id]}"
|
209
236
|
|
210
237
|
return [
|
211
238
|
before,
|
@@ -237,6 +264,15 @@ module JsDuck
|
|
237
264
|
]
|
238
265
|
end
|
239
266
|
|
267
|
+
if m[:template]
|
268
|
+
doc << [
|
269
|
+
"<div class='template'>",
|
270
|
+
"<p>This is a template method. A hook into the functionality of this class.",
|
271
|
+
"Feel free to override it in child classes.</p>",
|
272
|
+
"</div>",
|
273
|
+
]
|
274
|
+
end
|
275
|
+
|
240
276
|
doc << render_params_and_return(m)
|
241
277
|
|
242
278
|
doc
|
@@ -297,6 +333,7 @@ module JsDuck
|
|
297
333
|
end
|
298
334
|
|
299
335
|
def render_return(ret)
|
336
|
+
return if ret[:type] == "undefined"
|
300
337
|
return [
|
301
338
|
"<h3 class='pa'>Returns</h3>",
|
302
339
|
"<ul>",
|
data/lib/jsduck/search_data.rb
CHANGED
@@ -10,11 +10,13 @@ module JsDuck
|
|
10
10
|
list = []
|
11
11
|
docs.each do |cls|
|
12
12
|
list << class_node(cls)
|
13
|
-
[:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
[:members, :statics].each do |group|
|
14
|
+
[:cfg, :property, :method, :event].each do |type|
|
15
|
+
cls.members(type, group).each do |m|
|
16
|
+
# skip inherited items and constructors
|
17
|
+
if m[:owner] == cls.full_name && m[:name] != cls.short_name
|
18
|
+
list << member_node(m, cls)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -38,6 +40,7 @@ module JsDuck
|
|
38
40
|
:cls => cls.full_name,
|
39
41
|
:member => member[:name],
|
40
42
|
:type => member[:tagname],
|
43
|
+
:id => member[:id],
|
41
44
|
}
|
42
45
|
end
|
43
46
|
|
data/lib/jsduck/source_file.rb
CHANGED
@@ -15,9 +15,10 @@ module JsDuck
|
|
15
15
|
attr_reader :docs
|
16
16
|
attr_reader :html_filename
|
17
17
|
|
18
|
-
def initialize(contents, filename="")
|
18
|
+
def initialize(contents, filename="", options={})
|
19
19
|
@contents = contents
|
20
20
|
@filename = filename
|
21
|
+
@options = options
|
21
22
|
@html_filename = ""
|
22
23
|
@links = {}
|
23
24
|
|
@@ -69,7 +70,7 @@ module JsDuck
|
|
69
70
|
else
|
70
71
|
# when creation of global class is skipped,
|
71
72
|
# this owner property can be nil.
|
72
|
-
(doc[:owner] || "global").gsub(/\./, '-') + "-" + doc[:
|
73
|
+
(doc[:owner] || "global").gsub(/\./, '-') + "-" + doc[:id]
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
@@ -78,9 +79,9 @@ module JsDuck
|
|
78
79
|
# Parses the file depending on filename as JS or CSS
|
79
80
|
def parse
|
80
81
|
if @filename =~ /\.s?css$/
|
81
|
-
CssParser.new(@contents).parse
|
82
|
+
CssParser.new(@contents, @options).parse
|
82
83
|
else
|
83
|
-
JsParser.new(@contents).parse
|
84
|
+
JsParser.new(@contents, @options).parse
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|