@@ -1273,8 +1273,49 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
1273
1273
searchState . setup ( ) ;
1274
1274
} ( ) ) ;
1275
1275
1276
- // This section handles sidebar resizing
1276
+ // Hide, show, and resize the sidebar
1277
+ //
1278
+ // The body class and CSS variable are initially set up in storage.js,
1279
+ // but in this file, we implement:
1280
+ //
1281
+ // * the show sidebar button, which appears if the sidebar is hidden
1282
+ // and, by clicking on it, will bring it back
1283
+ // * the sidebar resize handle, which appears only on large viewports
1284
+ // with a [fine precision pointer] to allow the user to change
1285
+ // the size of the sidebar
1286
+ //
1287
+ // [fine precision pointer]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
1277
1288
( function ( ) {
1289
+ // 100 is the size of the logo
1290
+ // don't let the sidebar get smaller than that, or it'll get squished
1291
+ const SIDEBAR_MIN = 100 ;
1292
+ // Don't let the sidebar get bigger than this
1293
+ const SIDEBAR_MAX = 500 ;
1294
+ // Don't let the body (including the gutter) get smaller than this
1295
+ //
1296
+ // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
1297
+ // Acceptable values for BODY_MIN are constrained by the mobile breakpoint
1298
+ // (which is the minimum size of the whole page where the sidebar exists)
1299
+ // and the default sidebar width:
1300
+ //
1301
+ // BODY_MIN <= RUSTDOC_MOBILE_BREAKPOINT - DEFAULT_SIDEBAR_WIDTH
1302
+ //
1303
+ // At the time of this writing, the DEFAULT_SIDEBAR_WIDTH on src pages is
1304
+ // 300px, and the RUSTDOC_MOBILE_BREAKPOINT is 700px, so BODY_MIN must be
1305
+ // at most 400px. Otherwise, it would start out at the default size, then
1306
+ // grabbing the resize handle would suddenly cause it to jank to
1307
+ // its contraint-generated maximum.
1308
+ const BODY_MIN = 400 ;
1309
+ // At half-way past the minimum size, vanish the sidebar entirely
1310
+ const SIDEBAR_VANISH_THRESHOLD = SIDEBAR_MIN / 2 ;
1311
+
1312
+ // Toolbar button to show the sidebar.
1313
+ //
1314
+ // On small, "mobile-sized" viewports, it's not persistent and it
1315
+ // can only be activated by going into Settings and hiding the nav bar.
1316
+ // On larger, "desktop-sized" viewports (though that includes many
1317
+ // tablets), it's fixed-position, appears in the left side margin,
1318
+ // and it can be activated by resizing the sidebar into nothing.
1278
1319
const sidebarButton = document . getElementById ( "sidebar-button" ) ;
1279
1320
if ( sidebarButton ) {
1280
1321
sidebarButton . addEventListener ( "click" , e => {
@@ -1283,13 +1324,38 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
1283
1324
e . preventDefault ( ) ;
1284
1325
} ) ;
1285
1326
}
1327
+
1328
+ // Pointer capture.
1329
+ //
1330
+ // Resizing is a single-pointer gesture. Any secondary pointer is ignored
1286
1331
let currentPointerId = null ;
1332
+
1333
+ // "Desired" sidebar size.
1334
+ //
1335
+ // This is stashed here for window resizing. If the sidebar gets
1336
+ // shrunk to maintain BODY_MIN, and then the user grows the window again,
1337
+ // it gets the sidebar to restore its size.
1338
+ let desiredSidebarSize = null ;
1339
+
1340
+ // If this page has no sidebar at all, bail out.
1287
1341
const resizer = document . querySelector ( ".sidebar-resizer" ) ;
1288
1342
const sidebar = document . querySelector ( ".sidebar" ) ;
1289
1343
if ( ! resizer || ! sidebar ) {
1290
1344
return ;
1291
1345
}
1346
+
1347
+ // src page and docs page use different variables, because the contents of
1348
+ // the sidebar are so different that it's reasonable to thing the user
1349
+ // would want them to have different sizes
1292
1350
const isSrcPage = hasClass ( document . body , "src" ) ;
1351
+
1352
+ // Call this function to hide the sidebar when using the resize handle
1353
+ //
1354
+ // This function also nulls out the sidebar width CSS variable and setting,
1355
+ // causing it to return to its default. This does not happen if you do it
1356
+ // from settings.js, which uses a separate function. It's done here because
1357
+ // the minimum sidebar size is rather uncomfortable, and it must pass
1358
+ // through that size when using the shrink-to-nothing gesture.
1293
1359
function hideSidebar ( ) {
1294
1360
if ( isSrcPage ) {
1295
1361
window . rustdocCloseSourceSidebar ( ) ;
@@ -1302,6 +1368,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
1302
1368
document . documentElement . style . removeProperty ( "--desktop-sidebar-width" ) ;
1303
1369
}
1304
1370
}
1371
+
1372
+ // Call this function to show the sidebar from the resize handle.
1373
+ // On docs pages, this can only happen if the user has grabbed the resize
1374
+ // handle, shrunk the sidebar down to nothing, and then pulls back into
1375
+ // the visible range without releasing it. You can, however, grab the
1376
+ // resize handle on a source page with the sidebar closed, because it
1377
+ // remains visible all the time on there.
1305
1378
function showSidebar ( ) {
1306
1379
if ( isSrcPage ) {
1307
1380
window . rustdocShowSourceSidebar ( ) ;
@@ -1310,6 +1383,9 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
1310
1383
updateLocalStorage ( "hide-sidebar" , "false" ) ;
1311
1384
}
1312
1385
}
1386
+
1387
+ // Call this to set the correct CSS variable and setting.
1388
+ // This function doesn't enforce size constraints. Do that before calling it!
1313
1389
function changeSidebarSize ( size ) {
1314
1390
if ( isSrcPage ) {
1315
1391
updateLocalStorage ( "src-sidebar-width" , size ) ;
@@ -1319,34 +1395,54 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
1319
1395
document . documentElement . style . setProperty ( "--desktop-sidebar-width" , size + "px" ) ;
1320
1396
}
1321
1397
}
1398
+
1399
+ // Check if the sidebar is hidden. Since src pages and doc pages have
1400
+ // different settings, this function has to check that.
1322
1401
function isSidebarHidden ( ) {
1323
1402
return isSrcPage ?
1324
1403
! hasClass ( document . documentElement , "src-sidebar-expanded" ) :
1325
1404
hasClass ( document . documentElement , "hide-sidebar" ) ;
1326
1405
}
1406
+
1407
+ // Respond to the resize handle event.
1408
+ // This function enforces size constraints, and implements the
1409
+ // shrink-to-nothing gesture based on thresholds defined above.
1327
1410
function resize ( e ) {
1328
1411
if ( currentPointerId === null || currentPointerId !== e . pointerId ) {
1329
1412
return ;
1330
1413
}
1331
1414
e . preventDefault ( ) ;
1332
1415
const pos = e . clientX - sidebar . offsetLeft - 3 ;
1333
- if ( pos < 50 ) {
1416
+ if ( pos < SIDEBAR_VANISH_THRESHOLD ) {
1334
1417
hideSidebar ( ) ;
1335
- } else if ( pos >= 100 ) {
1336
- // 100 is the size of the logo
1337
- // don't let the sidebar get smaller than that, or it'll get squished
1418
+ } else if ( pos >= SIDEBAR_MIN ) {
1338
1419
if ( isSidebarHidden ( ) ) {
1339
1420
showSidebar ( ) ;
1340
1421
}
1341
- // don't let the sidebar get wider than 500
1342
- changeSidebarSize ( Math . min ( pos , window . innerWidth - 100 , 500 ) ) ;
1422
+ // don't let the sidebar get wider than SIDEBAR_MAX, or the body narrower
1423
+ // than BODY_MIN
1424
+ const constrainedPos = Math . min ( pos , window . innerWidth - BODY_MIN , SIDEBAR_MAX ) ;
1425
+ changeSidebarSize ( constrainedPos ) ;
1426
+ desiredSidebarSize = constrainedPos ;
1343
1427
}
1344
1428
}
1429
+ // Respond to the window resize event.
1430
+ window . addEventListener ( "resize" , ( ) => {
1431
+ stopResize ( ) ;
1432
+ if ( desiredSidebarSize >= ( window . innerWidth - BODY_MIN ) ) {
1433
+ changeSidebarSize ( window . innerWidth - BODY_MIN ) ;
1434
+ } else if ( desiredSidebarSize !== null && desiredSidebarSize > SIDEBAR_MIN ) {
1435
+ changeSidebarSize ( desiredSidebarSize ) ;
1436
+ }
1437
+ } ) ;
1345
1438
function stopResize ( e ) {
1346
1439
if ( currentPointerId === null ) {
1347
1440
return ;
1348
1441
}
1349
- e . preventDefault ( ) ;
1442
+ if ( e ) {
1443
+ e . preventDefault ( ) ;
1444
+ }
1445
+ desiredSidebarSize = sidebar . getBoundingClientRect ( ) . width ;
1350
1446
removeClass ( resizer , "active" ) ;
1351
1447
window . removeEventListener ( "pointermove" , resize , false ) ;
1352
1448
window . removeEventListener ( "pointerup" , stopResize , false ) ;
@@ -1376,6 +1472,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
1376
1472
window . addEventListener ( "pointerup" , stopResize , false ) ;
1377
1473
addClass ( resizer , "active" ) ;
1378
1474
addClass ( document . documentElement , "sidebar-resizing" ) ;
1475
+ desiredSidebarSize = null ;
1379
1476
}
1380
1477
resizer . addEventListener ( "pointerdown" , initResize , false ) ;
1381
1478
} ( ) ) ;
0 commit comments