blob: 1e4362e9d58ed2e5ed1493e39f1e5ee6eb091715 [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:js_interop';
import 'package:web/web.dart';
import 'search.dart' show ElementExtension;
/// Initialize the sidebar contents and sidenav toggle handlers.
void init() {
_initializeContents();
_initializeToggles();
}
void _initializeToggles() {
final leftNavToggle = document.getElementById('sidenav-left-toggle');
final leftDrawer = document.querySelector('.sidebar-offcanvas-left');
final overlayElement = document.getElementById('overlay-under-drawer');
final toggleDrawerAndOverlay = (Event _) {
leftDrawer?.classList.toggle('active');
overlayElement?.classList.toggle('active');
}.toJS;
overlayElement?.addEventListener('click', toggleDrawerAndOverlay);
leftNavToggle?.addEventListener('click', toggleDrawerAndOverlay);
}
void _initializeContents() {
final body = document.body;
if (body == null) {
return;
}
final dataUsingBaseHref = body.getAttribute('data-using-base-href');
if (dataUsingBaseHref == null) {
// This should never happen.
assert(false, '"data-using-base-href" attribute on "body" is null.');
return;
}
final String baseHref;
if (dataUsingBaseHref != 'true') {
final dataBaseHref = body.getAttribute('data-base-href');
if (dataBaseHref == null) {
return;
}
baseHref = dataBaseHref;
} else {
baseHref = '';
}
final mainContent = document.getElementById('dartdoc-main-content');
if (mainContent == null) {
return;
}
final aboveSidebarPath = mainContent.getAttribute('data-above-sidebar');
final leftSidebar = document.getElementById('dartdoc-sidebar-left-content');
_loadSidebar(baseHref, aboveSidebarPath, leftSidebar);
final belowSidebarPath = mainContent.getAttribute('data-below-sidebar');
final rightSidebar = document.getElementById('dartdoc-sidebar-right');
_loadSidebar(baseHref, belowSidebarPath, rightSidebar);
}
void _loadSidebar(
String baseHref,
String? sidebarPath,
Element? sidebarElement,
) {
if (sidebarPath == null || sidebarPath.isEmpty || sidebarElement == null) {
return;
}
window.fetch('$baseHref$sidebarPath'.toJS).toDart.then((fetchResponse) async {
if (fetchResponse.status != HttpStatus.ok) {
final errorAnchor = HTMLAnchorElement()
..href = 'https://dart.dev/tools/dart-doc#troubleshoot'
..text = 'Failed to load sidebar. '
'Visit dart.dev for help troubleshooting.';
sidebarElement.appendChild(errorAnchor);
return;
}
final responseText = (await fetchResponse.text().toDart).toDart;
final sidebarContent = HTMLDivElement()..innerHtml = responseText;
_updateLinks(baseHref, sidebarContent);
sidebarElement.appendChild(sidebarContent);
});
}
/// Recurses down a DOM tree to adjust the links in a newly loaded sidebar
/// if "base href" is not being used.
void _updateLinks(String baseHref, Node node) {
if (node.isA<HTMLAnchorElement>()) {
final hrefValue =
(node as HTMLAnchorElement).attributes.getNamedItem('href')?.value;
if (hrefValue == null) {
return;
}
final href = Uri.tryParse(hrefValue);
if (href != null && !href.isAbsolute) {
node.href = '$baseHref$hrefValue';
}
}
final children = node.childNodes;
for (var childIndex = 0; childIndex < children.length; childIndex += 1) {
if (children.item(childIndex) case final child?) {
_updateLinks(baseHref, child);
}
}
}