Commit 8eb75ae3 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Merge branch 'ext4-theme'

parents 33b360c3 061f5586
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
*.gem
template/extjs
template/resources/css
template/resources/sass/.sass-cache
sdk-vars.rb
+129 −0
Original line number Diff line number Diff line
@@ -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
+112 −20
Original line number Diff line number Diff line
@@ -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 = []
@@ -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

+46 −20
Original line number Diff line number Diff line
require 'jsduck/class'

module JsDuck

  # Combines JavaScript Parser, DocParser and Merger.
@@ -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.
@@ -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
@@ -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 = []
@@ -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

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