@@ -67,12 +67,10 @@ use html::item_type::ItemType;
67
67
use html:: layout;
68
68
use html:: markdown:: Markdown ;
69
69
use html:: markdown;
70
- use html:: escape:: Escape ;
71
70
use stability_summary;
72
71
73
72
/// A pair of name and its optional document.
74
- #[ derive( Clone , Eq , Ord , PartialEq , PartialOrd ) ]
75
- pub struct NameDoc ( String , Option < String > ) ;
73
+ pub type NameDoc = ( String , Option < String > ) ;
76
74
77
75
/// Major driving force in all rustdoc rendering. This contains information
78
76
/// about where in the tree-like hierarchy rendering is occurring and controls
@@ -98,12 +96,6 @@ pub struct Context {
98
96
/// This describes the layout of each page, and is not modified after
99
97
/// creation of the context (contains info like the favicon and added html).
100
98
pub layout : layout:: Layout ,
101
- /// This map is a list of what should be displayed on the sidebar of the
102
- /// current page. The key is the section header (traits, modules,
103
- /// functions), and the value is the list of containers belonging to this
104
- /// header. This map will change depending on the surrounding context of the
105
- /// page.
106
- pub sidebar : HashMap < String , Vec < NameDoc > > ,
107
99
/// This flag indicates whether [src] links should be generated or not. If
108
100
/// the source files are present in the html rendering, then this will be
109
101
/// `true`.
@@ -271,7 +263,6 @@ pub fn run(mut krate: clean::Crate,
271
263
passes : passes,
272
264
current : Vec :: new ( ) ,
273
265
root_path : String :: new ( ) ,
274
- sidebar : HashMap :: new ( ) ,
275
266
layout : layout:: Layout {
276
267
logo : "" . to_string ( ) ,
277
268
favicon : "" . to_string ( ) ,
@@ -1232,7 +1223,16 @@ impl Context {
1232
1223
clean:: ModuleItem ( m) => m,
1233
1224
_ => unreachable ! ( )
1234
1225
} ;
1235
- this. sidebar = this. build_sidebar ( & m) ;
1226
+
1227
+ // render sidebar-items.js used throughout this module
1228
+ {
1229
+ let items = this. build_sidebar_items ( & m) ;
1230
+ let js_dst = this. dst . join ( "sidebar-items.js" ) ;
1231
+ let mut js_out = BufferedWriter :: new ( try!( File :: create ( & js_dst) ) ) ;
1232
+ try!( write ! ( & mut js_out, "initSidebarItems({});" ,
1233
+ json:: as_json( & items) ) ) ;
1234
+ }
1235
+
1236
1236
for item in m. items {
1237
1237
f ( this, item) ;
1238
1238
}
@@ -1252,15 +1252,11 @@ impl Context {
1252
1252
}
1253
1253
}
1254
1254
1255
- fn build_sidebar ( & self , m : & clean:: Module ) -> HashMap < String , Vec < NameDoc > > {
1255
+ fn build_sidebar_items ( & self , m : & clean:: Module ) -> HashMap < String , Vec < NameDoc > > {
1256
1256
let mut map = HashMap :: new ( ) ;
1257
1257
for item in & m. items {
1258
1258
if self . ignore_private_item ( item) { continue }
1259
1259
1260
- // avoid putting foreign items to the sidebar.
1261
- if let & clean:: ForeignFunctionItem ( ..) = & item. inner { continue }
1262
- if let & clean:: ForeignStaticItem ( ..) = & item. inner { continue }
1263
-
1264
1260
let short = shortty ( item) . to_static_str ( ) ;
1265
1261
let myname = match item. name {
1266
1262
None => continue ,
@@ -1269,7 +1265,7 @@ impl Context {
1269
1265
let short = short. to_string ( ) ;
1270
1266
let v = map. entry ( short) . get ( ) . unwrap_or_else (
1271
1267
|vacant_entry| vacant_entry. insert ( Vec :: with_capacity ( 1 ) ) ) ;
1272
- v. push ( NameDoc ( myname, Some ( shorter_line ( item. doc_value ( ) ) ) ) ) ;
1268
+ v. push ( ( myname, Some ( shorter_line ( item. doc_value ( ) ) ) ) ) ;
1273
1269
}
1274
1270
1275
1271
for ( _, items) in & mut map {
@@ -2216,9 +2212,18 @@ impl<'a> fmt::Display for Sidebar<'a> {
2216
2212
fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
2217
2213
let cx = self . cx ;
2218
2214
let it = self . item ;
2215
+ let parentlen = cx. current . len ( ) - if it. is_mod ( ) { 1 } else { 0 } ;
2216
+
2217
+ // the sidebar is designed to display sibling functions, modules and
2218
+ // other miscellaneous informations. since there are lots of sibling
2219
+ // items (and that causes quadratic growth in large modules),
2220
+ // we refactor common parts into a shared JavaScript file per module.
2221
+ // still, we don't move everything into JS because we want to preserve
2222
+ // as much HTML as possible in order to allow non-JS-enabled browsers
2223
+ // to navigate the documentation (though slightly inefficiently).
2224
+
2219
2225
try!( write ! ( fmt, "<p class='location'>" ) ) ;
2220
- let len = cx. current . len ( ) - if it. is_mod ( ) { 1 } else { 0 } ;
2221
- for ( i, name) in cx. current . iter ( ) . take ( len) . enumerate ( ) {
2226
+ for ( i, name) in cx. current . iter ( ) . take ( parentlen) . enumerate ( ) {
2222
2227
if i > 0 {
2223
2228
try!( write ! ( fmt, "::<wbr>" ) ) ;
2224
2229
}
@@ -2228,40 +2233,25 @@ impl<'a> fmt::Display for Sidebar<'a> {
2228
2233
}
2229
2234
try!( write ! ( fmt, "</p>" ) ) ;
2230
2235
2231
- fn block ( w : & mut fmt:: Formatter , short : & str , longty : & str ,
2232
- cur : & clean:: Item , cx : & Context ) -> fmt:: Result {
2233
- let items = match cx. sidebar . get ( short) {
2234
- Some ( items) => items,
2235
- None => return Ok ( ( ) )
2236
- } ;
2237
- try!( write ! ( w, "<div class='block {}'><h2>{}</h2>" , short, longty) ) ;
2238
- for & NameDoc ( ref name, ref doc) in items {
2239
- let curty = shortty ( cur) . to_static_str ( ) ;
2240
- let class = if cur. name . as_ref ( ) . unwrap ( ) == name &&
2241
- short == curty { "current" } else { "" } ;
2242
- try!( write ! ( w, "<a class='{ty} {class}' href='{href}{path}' \
2243
- title='{title}'>{name}</a>",
2244
- ty = short,
2245
- class = class,
2246
- href = if curty == "mod" { "../" } else { "" } ,
2247
- path = if short == "mod" {
2248
- format!( "{}/index.html" , name)
2249
- } else {
2250
- format!( "{}.{}.html" , short, name)
2251
- } ,
2252
- title = Escape ( doc. as_ref( ) . unwrap( ) ) ,
2253
- name = name) ) ;
2254
- }
2255
- try!( write ! ( w, "</div>" ) ) ;
2256
- Ok ( ( ) )
2236
+ // sidebar refers to the enclosing module, not this module
2237
+ let relpath = if shortty ( it) == ItemType :: Module { "../" } else { "" } ;
2238
+ try!( write ! ( fmt,
2239
+ "<script>window.sidebarCurrent = {{\
2240
+ name: '{name}', \
2241
+ ty: '{ty}', \
2242
+ relpath: '{path}'\
2243
+ }};</script>",
2244
+ name = it. name. as_ref( ) . map( |x| & x[ ..] ) . unwrap_or( "" ) ,
2245
+ ty = shortty( it) . to_static_str( ) ,
2246
+ path = relpath) ) ;
2247
+ if parentlen == 0 {
2248
+ // there is no sidebar-items.js beyond the crate root path
2249
+ // FIXME maybe dynamic crate loading can be merged here
2250
+ } else {
2251
+ try!( write ! ( fmt, "<script async src=\" {path}sidebar-items.js\" ></script>" ,
2252
+ path = relpath) ) ;
2257
2253
}
2258
2254
2259
- try!( block ( fmt, "mod" , "Modules" , it, cx) ) ;
2260
- try!( block ( fmt, "struct" , "Structs" , it, cx) ) ;
2261
- try!( block ( fmt, "enum" , "Enums" , it, cx) ) ;
2262
- try!( block ( fmt, "trait" , "Traits" , it, cx) ) ;
2263
- try!( block ( fmt, "fn" , "Functions" , it, cx) ) ;
2264
- try!( block ( fmt, "macro" , "Macros" , it, cx) ) ;
2265
2255
Ok ( ( ) )
2266
2256
}
2267
2257
}
0 commit comments