Commit 6e86106d authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Support nested grouping of assets.

Nested groups can be defined as follows:

    [{
        "title": "Main group",
        "items": [
            {"title: "subgroup",
             "items: [ ... ]}
        ]
    }]

In UI the tree will then show subfolders for the nested asset groups.
But the ThumbList display will still show all the assets in old way,
and the assets in subgroups will be expanded so they will appear as if
they were listed directly inside the top level group.

I guess in some way this beats the whole point of having the subgroups -
as all the assets still show up on the main page as if there were no
subgroups at all.  On the other hand we now technically have support for
subgroups, but I feel that's not really what these users were after when
they asked for nested grouping.

Additionally eliminated :dup_asset warning.  It didn't fit nicely to the
new way of iterating over assets, and I think it wasn't such a useful
warning anyway.
parent f7bfe1b8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ module JsDuck
      @groups = Util::Json.read(filename)
      @opts = opts
      fix_examples_data
      build_map_by_name("Two examples have the same name", filename)
      build_map_by_name
    end

    # Prefix all relative URL-s in examples list with path given in --examples-base-url
+27 −16
Original line number Diff line number Diff line
@@ -10,20 +10,10 @@ module JsDuck
  class GroupedAsset
    # Should be called from constructor after @groups have been read in,
    # and after it's been ensured that all items in groupes have names.
    #
    # Prints warning when there is a duplicate item within a group.
    # The warning message should say something like "duplicate <asset type>"
    def build_map_by_name(warning_msg, filename)
    def build_map_by_name
      @map_by_name = {}
      @groups.each do |group|
        group_map = {}
        group["items"].each do |item|
          if group_map[item["name"]]
            Logger.instance.warn(:dup_asset, "#{warning_msg} '#{item['name']}'", filename)
          end
      each_item do |item|
        @map_by_name[item["name"]] = item
          group_map[item["name"]] = item
        end
      end
    end

@@ -33,9 +23,30 @@ module JsDuck
    end

    # Iterates over all items in all groups
    def each_item
      @groups.each do |group|
        group["items"].each {|item| yield item }
    def each_item(group=nil, &block)
      group = group || @groups

      group.each do |item|
        if item["items"]
          each_item(item["items"], &block)
        else
          block.call(item)
        end
      end
    end

    def map_items(group=nil, &block)
      group = group || @groups

      group.map do |item|
        if item["items"]
          {
            "title" => item["title"],
            "items" => map_items(item["items"], &block)
          }
        else
          block.call(item)
        end
      end
    end

+16 −14
Original line number Diff line number Diff line
@@ -24,9 +24,10 @@ module JsDuck
    def initialize(filename, formatter, opts)
      @path = File.dirname(filename)
      @groups = Util::Json.read(filename)
      build_map_by_name("Two guides have the same name", filename)
      @formatter = formatter
      @opts = opts
      build_map_by_name
      load_all_guides
    end

    # Writes all guides to given dir in JsonP format
@@ -35,23 +36,16 @@ module JsDuck
      each_item {|guide| write_guide(guide, dir) }
    end

    # Modified each_item that also loads HTML for each guide
    def each_item
      super do |guide|
        # Load the guide if not loaded
        guide[:html] = load_guide(guide) if guide[:html] == nil
        # Pass guide to block if it was successfully loaded.
        yield guide if guide[:html]
    def load_all_guides
      each_item do |guide|
        guide[:html] = load_guide(guide)
      end
    end

    # Modified to_array that excludes the :html from guide nodes
    def to_array
      @groups.map do |group|
        {
          "title" => group["title"],
          "items" => group["items"].map {|g| Hash[g.select {|k, v| k != :html }] }
        }
      map_items do |item|
        Hash[item.select {|k, v| k != :html }]
      end
    end

@@ -141,7 +135,7 @@ module JsDuck
        [
          "<h3>#{group['title']}</h3>",
          "<ul>",
          group["items"].map {|g| "<li><a href='#!/guide/#{g['name']}'>#{g['title']}</a></li>" },
          flatten_subgroups(group["items"]).map {|g| "<li><a href='#!/guide/#{g['name']}'>#{g['title']}</a></li>" },
          "</ul>",
        ]
      end.flatten.join("\n")
@@ -153,6 +147,14 @@ module JsDuck
      EOHTML
    end

    def flatten_subgroups(items)
      result = []
      each_item(items) do |item|
        result << item
      end
      result
    end

    # Extracts guide icon URL from guide hash
    def icon_url(guide)
      "guides/" + guide["name"] + "/icon.png"
+0 −1
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ module JsDuck
        [:no_doc, "Member or class without documentation"],
        [:dup_param, "Method has two parameters with the same name"],
        [:dup_member, "Class has two members with the same name"],
        [:dup_asset, "Duplicate guide/video/example"],
        [:req_after_opt, "Required parameter comes after optional"],
        [:subproperty, "@param foo.bar where foo param doesn't exist"],
        [:sing_static, "Singleton class member marked as @static"],
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ module JsDuck
    def initialize(filename)
      @groups = Util::Json.read(filename)
      add_names_if_missing
      build_map_by_name("Two videos have the same name", filename)
      build_map_by_name
    end

    # Each video should have a name, which is used in URL to reference the video.
Loading