|
56 | 56 | const domErrors = document.getElementById("errors");
|
57 | 57 | const domErrorsText = document.getElementById("errorsText");
|
58 | 58 |
|
| 59 | + // Chosen to prevent collisions with the IDs above. |
| 60 | + const navPrefix = "nav_"; |
| 61 | + |
59 | 62 | var searchTimer = null;
|
60 | 63 |
|
61 | 64 | const curNav = {
|
|
67 | 70 | decl: null,
|
68 | 71 | // string file name matching tarball path
|
69 | 72 | path: null,
|
| 73 | + // string decl path within source file |
| 74 | + scrollToDeclPath: null, |
70 | 75 |
|
71 | 76 | // when this is populated, pressing the "view source" command will
|
72 | 77 | // navigate to this hash.
|
|
180 | 185 | } else {
|
181 | 186 | return renderDecl(curNav.decl);
|
182 | 187 | }
|
183 |
| - case 2: return renderSource(curNav.path); |
| 188 | + case 2: return renderSource(curNav.path, curNav.scrollToDeclPath); |
184 | 189 | default: throw new Error("invalid navigation state");
|
185 | 190 | }
|
186 | 191 | }
|
|
224 | 229 | }
|
225 | 230 | }
|
226 | 231 |
|
227 |
| - function renderSource(path) { |
228 |
| - const decl_index = findFileRoot(path); |
229 |
| - if (decl_index == null) return renderNotFound(); |
| 232 | + function renderSource(path, scroll_to_decl_path) { |
| 233 | + const root_index = findFileRoot(path); |
| 234 | + if (root_index == null) return renderNotFound(); |
230 | 235 |
|
231 |
| - renderNavFancy(decl_index, [{ |
| 236 | + renderNavFancy(root_index, [{ |
232 | 237 | name: "[src]",
|
233 | 238 | href: location.hash,
|
234 | 239 | }]);
|
235 | 240 |
|
236 |
| - domSourceText.innerHTML = declSourceHtml(decl_index); |
237 |
| - |
| 241 | + domSourceText.innerHTML = declSourceHtml(root_index, true); |
238 | 242 | domSectSource.classList.remove("hidden");
|
| 243 | + |
| 244 | + const scroll_to_decl_index = findDeclPathInNamespace(root_index, scroll_to_decl_path); |
| 245 | + if (scroll_to_decl_index !== null) { |
| 246 | + const to_elem = document.getElementById(navPrefix + scroll_to_decl_index); |
| 247 | + if (to_elem != null) { |
| 248 | + setTimeout(function() { |
| 249 | + to_elem.scrollIntoView(); |
| 250 | + }, 0); |
| 251 | + } |
| 252 | + } |
239 | 253 | }
|
240 | 254 |
|
241 | 255 | function renderDeclHeading(decl_index) {
|
242 | 256 | curNav.viewSourceHash = "#src/" + unwrapString(wasm_exports.decl_file_path(decl_index));
|
| 257 | + const is_root = wasm_exports.decl_is_root(decl_index); |
| 258 | + if (!is_root) { |
| 259 | + // E.g. if `decl_index` corresponds to `root.foo.bar` we want `foo.bar` |
| 260 | + var subcomponents = []; |
| 261 | + let decl_it = decl_index; |
| 262 | + while (decl_it != null) { |
| 263 | + subcomponents.push(declIndexName(decl_it)); |
| 264 | + decl_it = declParent(decl_it); |
| 265 | + } |
| 266 | + subcomponents.pop(); |
| 267 | + subcomponents.reverse(); |
| 268 | + curNav.viewSourceHash += ":" + subcomponents.join("."); |
| 269 | + } |
243 | 270 |
|
244 | 271 | const hdrNameSpan = domHdrName.children[0];
|
245 | 272 | const srcLink = domHdrName.children[1];
|
|
384 | 411 | if (members.length !== 0 || fields.length !== 0) {
|
385 | 412 | renderNamespace(decl_index, members, fields);
|
386 | 413 | } else {
|
387 |
| - domSourceText.innerHTML = declSourceHtml(decl_index); |
| 414 | + domSourceText.innerHTML = declSourceHtml(decl_index, false); |
388 | 415 | domSectSource.classList.remove("hidden");
|
389 | 416 | }
|
390 | 417 | }
|
|
414 | 441 | renderErrorSet(base_decl, errorSetNodeList(decl_index, errorSetNode));
|
415 | 442 | }
|
416 | 443 |
|
417 |
| - domSourceText.innerHTML = declSourceHtml(decl_index); |
| 444 | + domSourceText.innerHTML = declSourceHtml(decl_index, false); |
418 | 445 | domSectSource.classList.remove("hidden");
|
419 | 446 | }
|
420 | 447 |
|
|
428 | 455 | domTldDocs.classList.remove("hidden");
|
429 | 456 | }
|
430 | 457 |
|
431 |
| - domSourceText.innerHTML = declSourceHtml(decl_index); |
| 458 | + domSourceText.innerHTML = declSourceHtml(decl_index, false); |
432 | 459 | domSectSource.classList.remove("hidden");
|
433 | 460 | }
|
434 | 461 |
|
|
615 | 642 | curNav.tag = 0;
|
616 | 643 | curNav.decl = null;
|
617 | 644 | curNav.path = null;
|
| 645 | + curNav.scrollToDeclPath = null; |
618 | 646 | curNav.viewSourceHash = null;
|
619 | 647 | curNavSearch = "";
|
620 | 648 |
|
|
633 | 661 | const source_mode = nonSearchPart.startsWith("src/");
|
634 | 662 | if (source_mode) {
|
635 | 663 | curNav.tag = 2;
|
636 |
| - curNav.path = nonSearchPart.substring(4); |
| 664 | + const idpos = nonSearchPart.indexOf(":"); |
| 665 | + if (idpos === -1) { |
| 666 | + curNav.path = nonSearchPart.substring(4); |
| 667 | + } else { |
| 668 | + curNav.path = nonSearchPart.substring(4, idpos); |
| 669 | + curNav.scrollToDeclPath = nonSearchPart.substring(idpos + 1); |
| 670 | + } |
637 | 671 | } else {
|
638 | 672 | curNav.tag = 1;
|
639 | 673 | curNav.decl = findDecl(nonSearchPart);
|
|
904 | 938 | return unwrapString(wasm_exports.decl_name(decl_index));
|
905 | 939 | }
|
906 | 940 |
|
907 |
| - function declSourceHtml(decl_index) { |
908 |
| - return unwrapString(wasm_exports.decl_source_html(decl_index)); |
| 941 | + function declSourceHtml(decl_index, decl_nav_targets) { |
| 942 | + return unwrapString(wasm_exports.decl_source_html(decl_index, decl_nav_targets)); |
909 | 943 | }
|
910 | 944 |
|
911 | 945 | function declDoctestHtml(decl_index) {
|
|
973 | 1007 | return result;
|
974 | 1008 | }
|
975 | 1009 |
|
| 1010 | + function findDeclPathInNamespace(namespace_decl_index, path) { |
| 1011 | + setInputString(path); |
| 1012 | + const result = wasm_exports.find_decl_path_in_namespace(namespace_decl_index); |
| 1013 | + if (result === -1) return null; |
| 1014 | + return result; |
| 1015 | + } |
| 1016 | + |
976 | 1017 | function findFileRoot(path) {
|
977 | 1018 | setInputString(path);
|
978 | 1019 | const result = wasm_exports.find_file_root();
|
|
0 commit comments