Skip to content

Commit 1b44973

Browse files
committed
Improve UX of module explorer
1 parent 292c160 commit 1b44973

File tree

4 files changed

+98
-13
lines changed

4 files changed

+98
-13
lines changed

docs/_includes/js/custom.js

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,60 @@
11
// Handle opening/closing module overview list items
22
jtd.onReady(function(ready) {
3-
var moduleStructures = document.querySelectorAll('.module-structure');
4-
for (var i = 0; i < moduleStructures.length; i++) {
5-
jtd.addEvent(moduleStructures[i], 'click', function (e) {
3+
var forEach = function (list, callback) {
4+
for (var i = 0; i < list.length; i++) {
5+
callback(list[i])
6+
}
7+
};
8+
9+
// Bind listeners for expand all / collapse all functionality
10+
var bindToggleAll = function (selector, options) {
11+
var isOpen = options.open;
12+
var expandAllButtons = document.querySelectorAll(selector);
13+
forEach(expandAllButtons, function (button) {
14+
jtd.addEvent(button, 'click', function (e) {
15+
var originalTarget = e.target || e.srcElement || e.originalTarget;
16+
if (originalTarget.tagName !== 'A') { return; }
17+
18+
var moduleList = originalTarget.closest('.module-list');
19+
forEach(moduleList.querySelectorAll('.folder > ul'), function (list) {
20+
if (isOpen) {
21+
list.classList.add('open');
22+
} else {
23+
list.classList.remove('open');
24+
}
25+
})
26+
27+
e.preventDefault();
28+
});
29+
});
30+
};
31+
bindToggleAll('.module-list [data-expand-all]', { open: true })
32+
bindToggleAll('.module-list [data-collapse-all]', { open: false })
33+
34+
// Bind listeners for collapsing module navigation items
35+
var moduleStructureElements = document.querySelectorAll('.module-structure');
36+
forEach(moduleStructureElements, function (moduleStructure) {
37+
jtd.addEvent(moduleStructure, 'click', function (e) {
638
var originalTarget = e.target || e.srcElement || e.originalTarget;
739
if (originalTarget.tagName !== 'A') { return; }
840

941
var parentListItem = originalTarget.closest('li');
1042
if (parentListItem.className.indexOf('folder') === -1) { return; }
1143

12-
var childList = parentListItem.querySelector('ul');
13-
if (childList) {
14-
childList.classList.toggle('open');
15-
}
44+
toggleChildModuleList(parentListItem)
1645
e.preventDefault();
1746
});
47+
})
48+
49+
var toggleChildModuleList = function (parent) {
50+
var list = parent.querySelector('ul');
51+
if (!list) {
52+
return;
53+
}
54+
list.classList.toggle('open');
55+
// Recursively automatically open any nested lists of size 1
56+
if (list.children.length === 1) {
57+
toggleChildModuleList(list.children[0])
58+
}
1859
}
1960
});

docs/_plugins/metasploit_stats.rb

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
# Helper class for extracting information related to Metasploit framework's stats
77
#
88
class MetasploitStats
9+
def total_module_count
10+
modules.length
11+
end
12+
913
# @return [Hash<String, Integer>] A map of module type to the amount of modules
1014
def module_counts
1115
module_counts_by_type = modules.group_by { |mod| mod['type'].to_s }.transform_values { |mods| mods.count }.sort_by(&:first).to_h
@@ -71,11 +75,27 @@ def modules_by_fullname
7175
module ModuleFilter
7276
# @param [Array<Hash>] modules The array of Metasploit cache information
7377
# @return [String] The module tree HTML representation of the given modules
74-
def module_tree(modules)
78+
def module_tree(modules, title = 'Modules', show_controls = false)
7579
rendered_children = render_modules(modules)
80+
controls = <<~EOF
81+
<div class="module-controls">
82+
<span><a href="#" data-expand-all>Expand All</a></span>
83+
<span><a href="#" data-collapse-all>Collapse All</a></span>
84+
</div>
85+
EOF
7686

7787
<<~EOF
78-
<ul class="module-structure">#{rendered_children}</ul>
88+
<div class="module-list">
89+
#{show_controls ? controls : ''}
90+
91+
<ul class="module-structure">
92+
<li class="folder"><a href=\"#\"><div class=\"target\">#{title}</div></a>
93+
<ul class="open">
94+
#{rendered_children}
95+
</ul>
96+
</li>
97+
</ul>
98+
</div>
7999
EOF
80100
end
81101

@@ -85,7 +105,8 @@ def module_tree(modules)
85105
# @return [String] The rendered tree HTML representation of the given modules
86106
def render_modules(modules)
87107
modules.map do |mod|
88-
result = "<li#{render_child_modules?(mod) ? ' class="folder"' : ''}>#{heading_for_mod(mod)}"
108+
classes = render_child_modules?(mod) ? ' class="folder"' : ''
109+
result = "<li#{classes}>#{heading_for_mod(mod)}"
89110
if render_child_modules?(mod)
90111
result += "\n<ul>#{render_modules(mod[:children].sort_by { |mod| "#{render_child_modules?(mod) ? 0 : 1}-#{mod[:name]}" })}</ul>\n"
91112
end
@@ -126,7 +147,7 @@ def render_child_modules?(mod)
126147

127148
metasploit_stats = MetasploitStats.new
128149

129-
site.config['metasploit_total_module_count'] = metasploit_stats.module_counts.sum { |_type, count| count }
150+
site.config['metasploit_total_module_count'] = metasploit_stats.total_module_count
130151
site.config['metasploit_module_counts'] = metasploit_stats.module_counts
131152
site.config['metasploit_nested_module_counts'] = metasploit_stats.nested_module_counts
132153

docs/assets/css/main.css

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,32 @@
4545
width: 90%;
4646
}
4747

48+
.module-controls {
49+
line-height: 0;
50+
border-bottom: 1px solid #ddd;
51+
}
52+
53+
.module-controls a {
54+
line-height: 1;
55+
padding: 0.5rem;
56+
display: inline-block;
57+
}
58+
59+
.module-controls span {
60+
display: inline-block;
61+
}
62+
4863
.module-structure a, .module-structure a:hover {
4964
background-image: none;
5065
}
5166

52-
.module-structure a:hover .target {
67+
.module-structure a .target {
5368
pointer-events: none;
5469
display: inline-block;
5570
text-decoration: none;
71+
}
72+
73+
.module-structure a:hover .target {
5674
background-image: linear-gradient(rgba(114, 83, 237, 0.45) 0%, rgba(114, 83, 237, 0.45) 100%);
5775
background-repeat: repeat-x;
5876
background-position: 0 100%;
@@ -70,6 +88,11 @@
7088
border-left: 1px dashed #d1d7de;
7189
}
7290

91+
/* Never allow the top-most files/folders to be collapsed */
92+
.module-structure > li.folder > ul {
93+
display: block;
94+
}
95+
7396
.module-structure li p {
7497
margin: 0;
7598
}

docs/metasploit-framework.wiki/Modules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
There are currently {{ site.metasploit_total_module_count }} Metasploit modules:
44

5-
{{ site.metasploit_nested_module_counts | module_tree }}
5+
{{ site.metasploit_nested_module_counts | module_tree: "All Modules", true }}
66

77
## Module types
88

0 commit comments

Comments
 (0)