Loading .gitignore +4 −0 Original line number Diff line number Diff line *.gem template/extjs template/resources/css template/resources/sass/.sass-cache sdk-vars.rb Rakefile +129 −0 Original line number Diff line number Diff line Loading @@ -20,4 +20,133 @@ task :install => :build do system "gem install --user-install jsduck" end def load_sdk_vars if File.exists?("sdk-vars.rb") require "sdk-vars.rb" else puts "Error: sdk-vars.rb not found." puts puts "Please create file sdk-vars.rb and define constants SDK_DIR and OUT_DIR in it." puts puts "For example:" puts puts " SDK_DIR='/path/to/SDK'" puts " OUT_DIR='/path/to/ouput/dir'" puts " EXT_DIR='/path/to/ext/dir'" exit 1 end end def run_jsduck(extra_options) # Pass multiple arguments to system, so we'll take advantage of the built-in escaping system(*[ "ruby", "bin/jsduck", # --external=Error to ignore the Error class that Ext.Error extends. "--external", "Error", "--guides", "#{SDK_DIR}/guides", "--guides-order", "getting,class,application,layouts,data,grid,tree,drawing,forms,components,theming,direct", "--categories", "#{SDK_DIR}/extjs/doc-resources/categories.json", "--output", "#{OUT_DIR}", ].concat(extra_options)) # Finally copy over the images that documentation links to. system "cp -r #{SDK_DIR}/extjs/doc-resources #{OUT_DIR}/doc-resources" system "cp -r #{SDK_DIR}/platform/doc-resources/* #{OUT_DIR}/doc-resources" end desc "Run JSDuck on ExtJS SDK" task :sdk do load_sdk_vars run_jsduck([ "--extjs-path", "extjs/ext-debug.js", # to create symbolic links to template files instead of copying them over. # Useful for development. Turn off for deployment. "--template-links", "#{SDK_DIR}/extjs/src", "#{SDK_DIR}/platform/src", "#{SDK_DIR}/platform/core/src", ]) end def run_jsduck_export(extra_options, ext_dir) load_sdk_vars rev = `git rev-parse HEAD`.slice(0, 7) run_jsduck([ "--title", "Ext JS 4.0.2a API Documentation", "--footer", "ExtJS 4.0.2a Documentation from Sencha. Generated with <a href='https://github.com/nene/jsduck'>JSDuck</a> revison #{rev}", "#{SDK_DIR}/extjs/src", "#{SDK_DIR}/platform/src", "#{SDK_DIR}/platform/core/src", ].concat(extra_options)) system "rm #{OUT_DIR}/extjs" system "mkdir -p #{OUT_DIR}/extjs/resources/themes/images" system "cp #{EXT_DIR}/ext-all.js #{OUT_DIR}/extjs" system "cp -r #{ext_dir}/resources/themes/images/default #{OUT_DIR}/extjs/resources/themes/images" system "rm -rf #{ext_dir}/resources/sass" system "rm -rf #{OUT_DIR}/resources/.sass-cache" end desc "Run JSDuck on ExtJS SDK to create release version of docs app" task :export do load_sdk_vars run_jsduck_export([ "--append-html", <<-EOHTML <div id="notice-text" style="display: none"> Use <a href="http://docs.sencha.com/ext-js/4-0">http://docs.sencha.com/ext-js/4-0</a> for up to date documentation and features </div> EOHTML ], EXT_DIR) end desc "Run JSDuck on ExtJS SDK to create live docs app" task :live_docs do load_sdk_vars run_jsduck_export([ "--append-html", <<-EOHTML <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-1396058-10']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); Docs.initEventTracking = function() { Docs.App.getController('Classes').addListener({ showClass: function(cls) { _gaq.push(['_trackEvent', 'Classes', 'Show', cls]); }, showMember: function(cls, anchor) { _gaq.push(['_trackEvent', 'Classes', 'Member', cls + ' - ' + anchor]); }, showGuide: function(guide) { _gaq.push(['_trackEvent', 'Guides', 'Show', guide]); } }); } </script> EOHTML ], "#{SDK_DIR}/extjs/build/sdk") end desc "Run JSDuck on the Docs app itself" task :docs do load_sdk_vars run_jsduck([ "--template-links", "#{SDK_DIR}/extjs/src", "#{SDK_DIR}/platform/src", "#{SDK_DIR}/platform/core/src", "template/app", "template/app.js", ]) end task :default => :spec bin/jsduck +112 −20 Original line number Diff line number Diff line Loading @@ -24,57 +24,137 @@ app = JsDuck::App.new app.template_dir = File.dirname(File.dirname(__FILE__)) + "/template" opts = OptionParser.new do | opts | opts.banner = "Usage: jsduck [options] files/dirs..." opts.banner = "Usage: jsduck [options] files/dirs...\n\n" opts.on('-o', '--output=PATH', "Directory to output all this amazing documentation.") do |path| opts.on('-o', '--output=PATH', "Directory to output all this amazing documentation.", "This option MUST be specified.", " ") do |path| app.output_dir = path end opts.on('-t', '--template=PATH', "Directory containing doc-browser UI template.") do |path| app.template_dir = path opts.on('--ignore-global', "Turns off the creation of global class.", " ") do app.ignore_global = true end opts.on('--json', "Produces JSON export instead of HTML documentation.") do app.export = :json opts.on('--private-classes', "Include private classes to docs.", " ") do app.show_private_classes = true end opts.on('--external=CLASSNAME', "Declares an external class. When declared as", "external, inheriting from this class will not", "trigger warnings. Useful when you are extending", "a class for which you can not supply source code.", " ") do |classname| app.external_classes << classname end opts.on('--no-warnings', "Turns off warnings.", " ") do app.warnings = false end opts.on('-v', '--verbose', "This will fill up your console.", " ") do app.verbose = true end opts.on('--link=TPL', "HTML template for replacing {@link}.", opts.separator "Customizing output:" opts.separator "" opts.on('--title=TEXT', "Custom title for the documentation app.", "Defaults to 'ExtJS API Documentation'", " ") do |text| app.title = text end opts.on('--footer=TEXT', "Custom footer text for the documentation app.", "Defaults to: 'Generated with JSDuck.'", " ") do |text| app.footer = text end opts.on('--append-html=HTML', "Extra code to append to the index.html page.", " ") do |html| app.append_html = html end opts.on('--guides=PATH', "Path to guides directory.", "Each subdirectory of that is treated as a guide", "and is expectd to contain a REAME.md file,", "which will be converted into a README.js.", " ") do |path| app.guides_dir = path end opts.on('--guides-order=a,b,c', Array, "The order in which the guides should appear. When", "a guide name is not specified here, it will be excluded.", "You don't have to write the whole name of the guide,", "just the beginning of it, as long as it's unique.", " ") do |list| app.guides_order = list end opts.on('--categories=PATH', "Path to JSON file which defines categories for classes.", " ") do |path| app.categories_path = path end opts.on('--link=TPL', "HTML template for replacing {@link}.", "Possible placeholders:", "%c - full class name (e.g. 'Ext.Panel')", "%m - class member name (e.g. 'urlEncode')", "%M - class member name, prefixed with hash (e.g. '#urlEncode')", "%m - class member name prefixed with member type", " (e.g. 'method-urlEncode')", "%# - inserts '#' if member name present", "%- - inserts '-' if member name present", "%a - anchor text for link", "Default value in export: '<a href=\"%c%M\">%a</a>'") do |tpl| "Default is: '<a href=\"#/api/%c%-%m\" rel=\"%c%-%m\" class=\"docClass\">%a</a>'", " ") do |tpl| app.link_tpl = tpl end opts.on('--img=TPL', "HTML template for replacing {@img}.", opts.on('--img=TPL', "HTML template for replacing {@img}.", "Possible placeholders:", "%u - URL from @img tag (e.g. 'some/path.png')", "%a - alt text for image", "Default value in export: '<img src=\"%u\" alt=\"%a\"/>'") do |tpl| "Default is: '<p><img src=\"doc-resources/%u\" alt=\"%a\"></p>'", " ") do |tpl| app.img_tpl = tpl end opts.on('--json', "Produces JSON export instead of HTML documentation.", " ") do app.export = :json end opts.separator "Debugging:" opts.separator "" # For debugging it's often useful to set --processes=0 to get deterministic results. opts.on('-p', '--processes=COUNT', "The number of parallel processes to use.", opts.on('-p', '--processes=COUNT', "The number of parallel processes to use.", "Defaults to the number of processors/cores.", "Set to 0 to disable parallel processing completely.") do |count| "Set to 0 to disable parallel processing completely.", " ") do |count| app.processes = count.to_i end opts.on('--ignore-global', "Turns off the creation of global class.") do app.ignore_global = true opts.on('--template=PATH', "Directory containing doc-browser UI template.", " ") do |path| app.template_dir = path end opts.on('-v', '--verbose', "This will fill up your console.") do app.verbose = true opts.on('--template-links', "Instead of copying template files, create symbolic", "links. Useful for template files development.", "Only works on platforms supporting symbolic links.", " ") do app.template_links = true end opts.on('--extjs-path=PATH', "Path for main ExtJS JavaScript file. Useful for specifying", "something different than extjs/ext-all.js", " ") do |path| app.extjs_path = path end opts.on('-h', '--help', "Prints this help message") do opts.on('-h', '--help', "Prints this help message", " ") do puts opts exit end end js_files = [] Loading Loading @@ -102,7 +182,19 @@ elsif File.exists?(app.output_dir) && !File.directory?(app.output_dir) puts "Oh noes! The output directory is not really a directory at all :(" exit(1) elsif !File.exists?(File.dirname(app.output_dir)) puts "Oh noes! The parent directory for #{output_dir} doesn't exist." puts "Oh noes! The parent directory for #{app.output_dir} doesn't exist." exit(1) elsif !File.exists?(app.template_dir + "/extjs") puts "Oh noes! The template directory does not contain extjs/ directory :(" puts "Please copy ExtJS over to template/extjs or create symlink." puts "For example:" puts " $ cp -r /path/to/ext-4.0.0 " + app.template_dir + "/extjs" exit(1) elsif !File.exists?(app.template_dir + "/resources/css") puts "Oh noes! CSS files for custom ExtJS theme missing :(" puts "Please compile SASS files in template/resources/sass with compass." puts "For example:" puts " $ compass compile " + app.template_dir + "/resources/sass" exit(1) end Loading lib/jsduck/aggregator.rb +46 −20 Original line number Diff line number Diff line require 'jsduck/class' module JsDuck # Combines JavaScript Parser, DocParser and Merger. Loading Loading @@ -48,14 +50,16 @@ module JsDuck # Merges new class-doc into old one. def merge_classes(old, new) [:extends, :xtype, :singleton, :private].each do |tag| [:extends, :xtype, :singleton, :private, :protected].each do |tag| old[tag] = old[tag] || new[tag] end [:mixins, :alternateClassNames].each do |tag| [:mixins, :alternateClassNames, :xtypes].each do |tag| old[tag] = old[tag] + new[tag] end old[:doc] = old[:doc].length > 0 ? old[:doc] : new[:doc] old[:cfg] = old[:cfg] + new[:cfg] # Additionally the doc-comment can contain configs and constructor old[:members][:cfg] += new[:members][:cfg] old[:members][:method] += new[:members][:method] end # Tries to place members into classes where they belong. Loading @@ -68,39 +72,43 @@ module JsDuck # Items without @member belong by default to the preceding class. # When no class precedes them - they too are orphaned. def add_member(node) if node[:member] if @classes[node[:member]] @classes[node[:member]][node[:tagname]] << node if node[:owner] if @classes[node[:owner]] add_to_class(@classes[node[:owner]], node) else add_orphan(node) end elsif @current_class node[:member] = @current_class[:name] @current_class[ node[:tagname] ] << node node[:owner] = @current_class[:name] add_to_class(@current_class, node) else add_orphan(node) end end def add_to_class(cls, member) cls[member[:static] ? :statics : :members][member[:tagname]] << member end def add_orphan(node) @orphans << node end # Inserts available orphans to class def insert_orphans(cls) members = @orphans.find_all {|node| node[:member] == cls[:name] } members = @orphans.find_all {|node| node[:owner] == cls[:name] } members.each do |node| cls[node[:tagname]] << node add_to_class(cls, node) @orphans.delete(node) end end # Creates classes for orphans that have :member property defined, # Creates classes for orphans that have :owner property defined, # and then inserts orphans to these classes. def classify_orphans @orphans.each do |orph| if orph[:member] class_name = orph[:member] if orph[:owner] class_name = orph[:owner] if !@classes[class_name] add_empty_class(class_name) end Loading @@ -117,7 +125,7 @@ module JsDuck add_empty_class("global", "Global variables and functions.") @orphans.each do |orph| orph[:member] = "global" orph[:owner] = "global" add_member(orph) end @orphans = [] Loading @@ -130,18 +138,36 @@ module JsDuck :doc => doc, :mixins => [], :alternateClassNames => [], :cfg => [], :property => [], :method => [], :event => [], :css_var => [], :css_mixin => [], :members => Class.default_members_hash, :statics => Class.default_members_hash, :filename => "", :html_filename => "", :linenr => 0, }) end # Appends Ext4 options parameter to each event parameter list. # But only when we are dealing with Ext4 codebase. def append_ext4_event_options return unless ext4? options = { :tagname => :param, :name => "options", :type => "Object", :doc => "The options object passed to {@link Ext.util.Observable#addListener}." } @classes.each_value do |cls| cls[:members][:event].each {|e| e[:params] << options } end end # Are we dealing with ExtJS 4? # True if any of the classes is defined with Ext.define() def ext4? @documentation.any? {|cls| cls[:code_type] == :ext_define } end def result @documentation + @orphans end Loading lib/jsduck/aliases.rb 0 → 100644 +39 −0 Original line number Diff line number Diff line module JsDuck class Aliases def initialize(relations) @relations = relations end def resolve_all @relations.each do |cls| cls.each_member do |member| if member[:alias] resolve(member) end end end end # Copy over doc/params/return from original member to alias. def resolve(al) orig = find_original(al) al[:doc] = al[:doc] + "\n\n" + orig[:doc] al[:params] = orig[:params] if orig[:params] al[:return] = orig[:return] if orig[:return] end # Given aliased member, finds the original member. # If the original also happens to be an alias, continue recursively. def find_original(al) al_def = al[:alias] orig = @relations[al_def[:cls]].get_member(al_def[:member], al_def[:type] || al[:tagname]) if orig[:alias] find_original(orig) else orig end end end end Loading
.gitignore +4 −0 Original line number Diff line number Diff line *.gem template/extjs template/resources/css template/resources/sass/.sass-cache sdk-vars.rb
Rakefile +129 −0 Original line number Diff line number Diff line Loading @@ -20,4 +20,133 @@ task :install => :build do system "gem install --user-install jsduck" end def load_sdk_vars if File.exists?("sdk-vars.rb") require "sdk-vars.rb" else puts "Error: sdk-vars.rb not found." puts puts "Please create file sdk-vars.rb and define constants SDK_DIR and OUT_DIR in it." puts puts "For example:" puts puts " SDK_DIR='/path/to/SDK'" puts " OUT_DIR='/path/to/ouput/dir'" puts " EXT_DIR='/path/to/ext/dir'" exit 1 end end def run_jsduck(extra_options) # Pass multiple arguments to system, so we'll take advantage of the built-in escaping system(*[ "ruby", "bin/jsduck", # --external=Error to ignore the Error class that Ext.Error extends. "--external", "Error", "--guides", "#{SDK_DIR}/guides", "--guides-order", "getting,class,application,layouts,data,grid,tree,drawing,forms,components,theming,direct", "--categories", "#{SDK_DIR}/extjs/doc-resources/categories.json", "--output", "#{OUT_DIR}", ].concat(extra_options)) # Finally copy over the images that documentation links to. system "cp -r #{SDK_DIR}/extjs/doc-resources #{OUT_DIR}/doc-resources" system "cp -r #{SDK_DIR}/platform/doc-resources/* #{OUT_DIR}/doc-resources" end desc "Run JSDuck on ExtJS SDK" task :sdk do load_sdk_vars run_jsduck([ "--extjs-path", "extjs/ext-debug.js", # to create symbolic links to template files instead of copying them over. # Useful for development. Turn off for deployment. "--template-links", "#{SDK_DIR}/extjs/src", "#{SDK_DIR}/platform/src", "#{SDK_DIR}/platform/core/src", ]) end def run_jsduck_export(extra_options, ext_dir) load_sdk_vars rev = `git rev-parse HEAD`.slice(0, 7) run_jsduck([ "--title", "Ext JS 4.0.2a API Documentation", "--footer", "ExtJS 4.0.2a Documentation from Sencha. Generated with <a href='https://github.com/nene/jsduck'>JSDuck</a> revison #{rev}", "#{SDK_DIR}/extjs/src", "#{SDK_DIR}/platform/src", "#{SDK_DIR}/platform/core/src", ].concat(extra_options)) system "rm #{OUT_DIR}/extjs" system "mkdir -p #{OUT_DIR}/extjs/resources/themes/images" system "cp #{EXT_DIR}/ext-all.js #{OUT_DIR}/extjs" system "cp -r #{ext_dir}/resources/themes/images/default #{OUT_DIR}/extjs/resources/themes/images" system "rm -rf #{ext_dir}/resources/sass" system "rm -rf #{OUT_DIR}/resources/.sass-cache" end desc "Run JSDuck on ExtJS SDK to create release version of docs app" task :export do load_sdk_vars run_jsduck_export([ "--append-html", <<-EOHTML <div id="notice-text" style="display: none"> Use <a href="http://docs.sencha.com/ext-js/4-0">http://docs.sencha.com/ext-js/4-0</a> for up to date documentation and features </div> EOHTML ], EXT_DIR) end desc "Run JSDuck on ExtJS SDK to create live docs app" task :live_docs do load_sdk_vars run_jsduck_export([ "--append-html", <<-EOHTML <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-1396058-10']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); Docs.initEventTracking = function() { Docs.App.getController('Classes').addListener({ showClass: function(cls) { _gaq.push(['_trackEvent', 'Classes', 'Show', cls]); }, showMember: function(cls, anchor) { _gaq.push(['_trackEvent', 'Classes', 'Member', cls + ' - ' + anchor]); }, showGuide: function(guide) { _gaq.push(['_trackEvent', 'Guides', 'Show', guide]); } }); } </script> EOHTML ], "#{SDK_DIR}/extjs/build/sdk") end desc "Run JSDuck on the Docs app itself" task :docs do load_sdk_vars run_jsduck([ "--template-links", "#{SDK_DIR}/extjs/src", "#{SDK_DIR}/platform/src", "#{SDK_DIR}/platform/core/src", "template/app", "template/app.js", ]) end task :default => :spec
bin/jsduck +112 −20 Original line number Diff line number Diff line Loading @@ -24,57 +24,137 @@ app = JsDuck::App.new app.template_dir = File.dirname(File.dirname(__FILE__)) + "/template" opts = OptionParser.new do | opts | opts.banner = "Usage: jsduck [options] files/dirs..." opts.banner = "Usage: jsduck [options] files/dirs...\n\n" opts.on('-o', '--output=PATH', "Directory to output all this amazing documentation.") do |path| opts.on('-o', '--output=PATH', "Directory to output all this amazing documentation.", "This option MUST be specified.", " ") do |path| app.output_dir = path end opts.on('-t', '--template=PATH', "Directory containing doc-browser UI template.") do |path| app.template_dir = path opts.on('--ignore-global', "Turns off the creation of global class.", " ") do app.ignore_global = true end opts.on('--json', "Produces JSON export instead of HTML documentation.") do app.export = :json opts.on('--private-classes', "Include private classes to docs.", " ") do app.show_private_classes = true end opts.on('--external=CLASSNAME', "Declares an external class. When declared as", "external, inheriting from this class will not", "trigger warnings. Useful when you are extending", "a class for which you can not supply source code.", " ") do |classname| app.external_classes << classname end opts.on('--no-warnings', "Turns off warnings.", " ") do app.warnings = false end opts.on('-v', '--verbose', "This will fill up your console.", " ") do app.verbose = true end opts.on('--link=TPL', "HTML template for replacing {@link}.", opts.separator "Customizing output:" opts.separator "" opts.on('--title=TEXT', "Custom title for the documentation app.", "Defaults to 'ExtJS API Documentation'", " ") do |text| app.title = text end opts.on('--footer=TEXT', "Custom footer text for the documentation app.", "Defaults to: 'Generated with JSDuck.'", " ") do |text| app.footer = text end opts.on('--append-html=HTML', "Extra code to append to the index.html page.", " ") do |html| app.append_html = html end opts.on('--guides=PATH', "Path to guides directory.", "Each subdirectory of that is treated as a guide", "and is expectd to contain a REAME.md file,", "which will be converted into a README.js.", " ") do |path| app.guides_dir = path end opts.on('--guides-order=a,b,c', Array, "The order in which the guides should appear. When", "a guide name is not specified here, it will be excluded.", "You don't have to write the whole name of the guide,", "just the beginning of it, as long as it's unique.", " ") do |list| app.guides_order = list end opts.on('--categories=PATH', "Path to JSON file which defines categories for classes.", " ") do |path| app.categories_path = path end opts.on('--link=TPL', "HTML template for replacing {@link}.", "Possible placeholders:", "%c - full class name (e.g. 'Ext.Panel')", "%m - class member name (e.g. 'urlEncode')", "%M - class member name, prefixed with hash (e.g. '#urlEncode')", "%m - class member name prefixed with member type", " (e.g. 'method-urlEncode')", "%# - inserts '#' if member name present", "%- - inserts '-' if member name present", "%a - anchor text for link", "Default value in export: '<a href=\"%c%M\">%a</a>'") do |tpl| "Default is: '<a href=\"#/api/%c%-%m\" rel=\"%c%-%m\" class=\"docClass\">%a</a>'", " ") do |tpl| app.link_tpl = tpl end opts.on('--img=TPL', "HTML template for replacing {@img}.", opts.on('--img=TPL', "HTML template for replacing {@img}.", "Possible placeholders:", "%u - URL from @img tag (e.g. 'some/path.png')", "%a - alt text for image", "Default value in export: '<img src=\"%u\" alt=\"%a\"/>'") do |tpl| "Default is: '<p><img src=\"doc-resources/%u\" alt=\"%a\"></p>'", " ") do |tpl| app.img_tpl = tpl end opts.on('--json', "Produces JSON export instead of HTML documentation.", " ") do app.export = :json end opts.separator "Debugging:" opts.separator "" # For debugging it's often useful to set --processes=0 to get deterministic results. opts.on('-p', '--processes=COUNT', "The number of parallel processes to use.", opts.on('-p', '--processes=COUNT', "The number of parallel processes to use.", "Defaults to the number of processors/cores.", "Set to 0 to disable parallel processing completely.") do |count| "Set to 0 to disable parallel processing completely.", " ") do |count| app.processes = count.to_i end opts.on('--ignore-global', "Turns off the creation of global class.") do app.ignore_global = true opts.on('--template=PATH', "Directory containing doc-browser UI template.", " ") do |path| app.template_dir = path end opts.on('-v', '--verbose', "This will fill up your console.") do app.verbose = true opts.on('--template-links', "Instead of copying template files, create symbolic", "links. Useful for template files development.", "Only works on platforms supporting symbolic links.", " ") do app.template_links = true end opts.on('--extjs-path=PATH', "Path for main ExtJS JavaScript file. Useful for specifying", "something different than extjs/ext-all.js", " ") do |path| app.extjs_path = path end opts.on('-h', '--help', "Prints this help message") do opts.on('-h', '--help', "Prints this help message", " ") do puts opts exit end end js_files = [] Loading Loading @@ -102,7 +182,19 @@ elsif File.exists?(app.output_dir) && !File.directory?(app.output_dir) puts "Oh noes! The output directory is not really a directory at all :(" exit(1) elsif !File.exists?(File.dirname(app.output_dir)) puts "Oh noes! The parent directory for #{output_dir} doesn't exist." puts "Oh noes! The parent directory for #{app.output_dir} doesn't exist." exit(1) elsif !File.exists?(app.template_dir + "/extjs") puts "Oh noes! The template directory does not contain extjs/ directory :(" puts "Please copy ExtJS over to template/extjs or create symlink." puts "For example:" puts " $ cp -r /path/to/ext-4.0.0 " + app.template_dir + "/extjs" exit(1) elsif !File.exists?(app.template_dir + "/resources/css") puts "Oh noes! CSS files for custom ExtJS theme missing :(" puts "Please compile SASS files in template/resources/sass with compass." puts "For example:" puts " $ compass compile " + app.template_dir + "/resources/sass" exit(1) end Loading
lib/jsduck/aggregator.rb +46 −20 Original line number Diff line number Diff line require 'jsduck/class' module JsDuck # Combines JavaScript Parser, DocParser and Merger. Loading Loading @@ -48,14 +50,16 @@ module JsDuck # Merges new class-doc into old one. def merge_classes(old, new) [:extends, :xtype, :singleton, :private].each do |tag| [:extends, :xtype, :singleton, :private, :protected].each do |tag| old[tag] = old[tag] || new[tag] end [:mixins, :alternateClassNames].each do |tag| [:mixins, :alternateClassNames, :xtypes].each do |tag| old[tag] = old[tag] + new[tag] end old[:doc] = old[:doc].length > 0 ? old[:doc] : new[:doc] old[:cfg] = old[:cfg] + new[:cfg] # Additionally the doc-comment can contain configs and constructor old[:members][:cfg] += new[:members][:cfg] old[:members][:method] += new[:members][:method] end # Tries to place members into classes where they belong. Loading @@ -68,39 +72,43 @@ module JsDuck # Items without @member belong by default to the preceding class. # When no class precedes them - they too are orphaned. def add_member(node) if node[:member] if @classes[node[:member]] @classes[node[:member]][node[:tagname]] << node if node[:owner] if @classes[node[:owner]] add_to_class(@classes[node[:owner]], node) else add_orphan(node) end elsif @current_class node[:member] = @current_class[:name] @current_class[ node[:tagname] ] << node node[:owner] = @current_class[:name] add_to_class(@current_class, node) else add_orphan(node) end end def add_to_class(cls, member) cls[member[:static] ? :statics : :members][member[:tagname]] << member end def add_orphan(node) @orphans << node end # Inserts available orphans to class def insert_orphans(cls) members = @orphans.find_all {|node| node[:member] == cls[:name] } members = @orphans.find_all {|node| node[:owner] == cls[:name] } members.each do |node| cls[node[:tagname]] << node add_to_class(cls, node) @orphans.delete(node) end end # Creates classes for orphans that have :member property defined, # Creates classes for orphans that have :owner property defined, # and then inserts orphans to these classes. def classify_orphans @orphans.each do |orph| if orph[:member] class_name = orph[:member] if orph[:owner] class_name = orph[:owner] if !@classes[class_name] add_empty_class(class_name) end Loading @@ -117,7 +125,7 @@ module JsDuck add_empty_class("global", "Global variables and functions.") @orphans.each do |orph| orph[:member] = "global" orph[:owner] = "global" add_member(orph) end @orphans = [] Loading @@ -130,18 +138,36 @@ module JsDuck :doc => doc, :mixins => [], :alternateClassNames => [], :cfg => [], :property => [], :method => [], :event => [], :css_var => [], :css_mixin => [], :members => Class.default_members_hash, :statics => Class.default_members_hash, :filename => "", :html_filename => "", :linenr => 0, }) end # Appends Ext4 options parameter to each event parameter list. # But only when we are dealing with Ext4 codebase. def append_ext4_event_options return unless ext4? options = { :tagname => :param, :name => "options", :type => "Object", :doc => "The options object passed to {@link Ext.util.Observable#addListener}." } @classes.each_value do |cls| cls[:members][:event].each {|e| e[:params] << options } end end # Are we dealing with ExtJS 4? # True if any of the classes is defined with Ext.define() def ext4? @documentation.any? {|cls| cls[:code_type] == :ext_define } end def result @documentation + @orphans end Loading
lib/jsduck/aliases.rb 0 → 100644 +39 −0 Original line number Diff line number Diff line module JsDuck class Aliases def initialize(relations) @relations = relations end def resolve_all @relations.each do |cls| cls.each_member do |member| if member[:alias] resolve(member) end end end end # Copy over doc/params/return from original member to alias. def resolve(al) orig = find_original(al) al[:doc] = al[:doc] + "\n\n" + orig[:doc] al[:params] = orig[:params] if orig[:params] al[:return] = orig[:return] if orig[:return] end # Given aliased member, finds the original member. # If the original also happens to be an alias, continue recursively. def find_original(al) al_def = al[:alias] orig = @relations[al_def[:cls]].get_member(al_def[:member], al_def[:type] || al[:tagname]) if orig[:alias] find_original(orig) else orig end end end end