Commit 0af9e5b4 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Reimplement searching by aliases.

Matching aliases are now separately listed in search results, just
like alternateClassNames - they also use the same icon.

Each search data record now defines its own sorting order using
the "sort" field.  The filterMembers method in turn groups the
results by full-, beginning- and middle-matches. This significantly
simplifies the search algorithm - no more is there a special handling
of aliases.
parent 530d20f5
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -15,6 +15,12 @@ module JsDuck
          list << alt_node(name, cls)
        end

        cls[:aliases].each_pair do |key, items|
          items.each do |name|
            list << alias_node(key, name, cls)
          end
        end

        [:members, :statics].each do |group|
          cls[group].each_key do |type|
            cls.members(type, group).each do |m|
@@ -29,6 +35,18 @@ module JsDuck
      list
    end

    # Creates structure representing one alias
    def alias_node(key, name, cls)
      return {
        :cls => alias_display_name(key)+": "+name,
        :member => name,
        :type => :class,
        :icon => :subclass,
        :id => cls.full_name,
        :sort => 0,
      }
    end

    # Creates structure representing one class
    def class_node(cls)
      return {
@@ -36,8 +54,8 @@ module JsDuck
        :member => cls.short_name,
        :type => :class,
        :icon => :class,
        :aliases => cls[:aliases],
        :id => cls.full_name,
        :sort => 1,
      }
    end

@@ -49,6 +67,7 @@ module JsDuck
        :type => :class,
        :icon => :subclass,
        :id => cls.full_name,
        :sort => 2,
      }
    end

@@ -60,7 +79,19 @@ module JsDuck
        :type => :member,
        :icon => member[:tagname],
        :id => cls.full_name + "-" + member[:id],
        :sort => 3,
      }
    end

    # Some alias types are shown differently.
    # e.g. instead of "widget:" we show "xtype:"
    def alias_display_name(key)
      titles = {
        "widget" => "xtype",
        "plugin" => "ptype",
        "feature" => "ftype",
      }
      titles[key] || key
    end

  end
+14 −28
Original line number Diff line number Diff line
@@ -150,50 +150,36 @@ Ext.define('Docs.controller.Search', {
    },

    filterMembers: function(text) {
        var results = [[], [], [], [], [], [], [], []];
        var xFull=0, clsFull=1, mFull=2, xBeg=3, clsBeg=4, mBeg=5, clsMid=6, mMid=7;
        var hasDot = /\./.test(text);
        // Each record has its relative sorting order: 0..3
        var results = [
            [], [], [], [], // First we sort full matches: 0..3
            [], [], [], [], // Then matches in beginning: 4..7
            [], [], [], []  // Finally matches in middle: 8..11
        ];
        var searchFull = /[.:]/.test(text);
        var safeText = Ext.escapeRe(text);
        var reFull = new RegExp("^" + safeText + "$", "i");
        var reBeg = new RegExp("^" + safeText, "i");
        var reMid = new RegExp(safeText, "i");

        Ext.Array.forEach(Docs.data.search, function(r) {
            var is_class = r.type === "class";
            // when search text has "." in it, search from the full name (e.g. "Ext.Component.focus")
            // when search text has "." or ":" in it, search from the full name
            // (e.g. "Ext.Component.focus" or "xtype: grid")
            // Otherwise search from just the member name (e.g. "focus" or "Component")
            var name = hasDot ? r.cls + (is_class ? "" : "." + r.member) : r.member;
            var name = searchFull ? r.cls + (r.type === "class" ? "" : "." + r.member) : r.member;

            if (r.aliases && this.matchAlias(r.aliases, reFull)) {
                results[xFull].push(r);
            }
            else if (reFull.test(name)) {
                results[is_class ? clsFull : mFull].push(r);
            }
            else if (r.aliases && this.matchAlias(r.aliases, reBeg)) {
                results[xBeg].push(r);
            if (reFull.test(name)) {
                results[r.sort].push(r);
            }
            else if (reBeg.test(name)) {
                results[is_class ? clsBeg : mBeg].push(r);
                results[r.sort+4].push(r);
            }
            else if (reMid.test(name)) {
                results[is_class ? clsMid : mMid].push(r);
                results[r.sort+8].push(r);
            }
        }, this);

        return Ext.Array.flatten(results);
    },

    // true if alias matches regex
    matchAlias: function(aliases, regex) {
        for (var key in aliases) {
            if (aliases.hasOwnProperty(key)) {
                if (Ext.Array.some(aliases[key], function(x) {return regex.test(x);})) {
                    return true;
                }
            }
        }
        return false;
    }

});
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
Ext.define('Docs.store.Search', {
    extend: 'Ext.data.Store',

    fields: ['cls', 'member', 'type', 'icon', 'aliases', 'id'],
    fields: ['cls', 'member', 'type', 'icon', 'id', 'sort'],
    proxy: {
        type: 'memory',
        reader: {