diff --git a/src/Documentation/doc/index.md b/src/Documentation/doc/index.md index fcb4f0c4d..941e957a0 100644 --- a/src/Documentation/doc/index.md +++ b/src/Documentation/doc/index.md @@ -43,6 +43,7 @@ ## Resources +- [NS API documentation](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.ns.md) - [Learn to program](programming/learn.md) - [Remote API](programming/remote_api.md) - [Game Frozen or Stuck?](programming/game_frozen.md) diff --git a/src/ScriptEditor/ui/Toolbar.tsx b/src/ScriptEditor/ui/Toolbar.tsx index 45ceef1ca..366781922 100644 --- a/src/ScriptEditor/ui/Toolbar.tsx +++ b/src/ScriptEditor/ui/Toolbar.tsx @@ -15,7 +15,6 @@ import SettingsIcon from "@mui/icons-material/Settings"; import { makeTheme, sanitizeTheme } from "./themes"; -import { CONSTANTS } from "../../Constants"; import { Modal } from "../../ui/React/Modal"; import { Page } from "../../ui/Router"; import { Router } from "../../ui/GameRoot"; @@ -23,11 +22,8 @@ import { useBoolean } from "../../ui/React/hooks"; import { Settings } from "../../Settings/Settings"; import { OptionsModal, OptionsModalProps } from "./OptionsModal"; import { useScriptEditorContext } from "./ScriptEditorContext"; +import { getNsApiDocumentationUrl } from "../../utils/StringHelperFunctions"; -const docUrl = - "https://github.com/bitburner-official/bitburner-src/blob/" + - (CONSTANTS.isDevBranch ? "dev" : "stable") + - "/markdown/bitburner.ns.md"; type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor; interface IProps { @@ -75,7 +71,7 @@ export function Toolbar({ editor, onSave }: IProps) { Terminal (Ctrl/Cmd + b) - + Documentation diff --git a/src/ui/MD/a.tsx b/src/ui/MD/a.tsx index 317795c43..80720ba83 100644 --- a/src/ui/MD/a.tsx +++ b/src/ui/MD/a.tsx @@ -3,6 +3,7 @@ import { Link } from "@mui/material"; import { useNavigator } from "../React/Documentation"; import { CorruptableText } from "../React/CorruptableText"; import { Player } from "@player"; +import { getNsApiDocumentationUrl } from "../../utils/StringHelperFunctions"; export const isSpoiler = (title: string): boolean => title.includes("advanced/") && Player.sourceFileLvl(1) === 0; @@ -13,12 +14,19 @@ export const A = (props: React.PropsWithChildren<{ href?: string }>): React.Reac const onClick = (event: React.MouseEvent) => { navigator.navigate(ref, event.ctrlKey); }; - if (ref.startsWith("http")) + if (ref.startsWith("http")) { + let href = ref; + // The URL of NS API documentation in index.md always points to the stable branch, so we need to intercept it here + // and change it if necessary. + if (href === getNsApiDocumentationUrl(false)) { + href = getNsApiDocumentationUrl(); + } return ( - + {props.children} ); + } if (isSpoiler(ref)) return ( diff --git a/src/utils/StringHelperFunctions.ts b/src/utils/StringHelperFunctions.ts index 004f8d80c..792f27395 100644 --- a/src/utils/StringHelperFunctions.ts +++ b/src/utils/StringHelperFunctions.ts @@ -1,11 +1,12 @@ import { Settings } from "../Settings/Settings"; +import { CONSTANTS } from "../Constants"; /* Converts a date representing time in milliseconds to a string with the format H hours M minutes and S seconds e.g. 10000 -> "10 seconds" 120000 -> "2 minutes and 0 seconds" */ -function convertTimeMsToTimeElapsedString(time: number, showMilli = false): string { +export function convertTimeMsToTimeElapsedString(time: number, showMilli = false): string { const negFlag = time < 0; time = Math.abs(Math.floor(time)); const millisecondsPerSecond = 1000; @@ -51,7 +52,7 @@ function convertTimeMsToTimeElapsedString(time: number, showMilli = false): stri } // Finds the longest common starting substring in a set of strings -function longestCommonStart(strings: string[]): string { +export function longestCommonStart(strings: string[]): string { if (!containsAllStrings(strings)) { return ""; } @@ -72,12 +73,12 @@ function longestCommonStart(strings: string[]): string { } // Returns whether an array contains entirely of string objects -function containsAllStrings(arr: string[]): boolean { +export function containsAllStrings(arr: string[]): boolean { return arr.every((value) => typeof value === "string"); } // Generates a random alphanumeric string with N characters -function generateRandomString(n: number): string { +export function generateRandomString(n: number): string { let str = ""; const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -95,7 +96,7 @@ function generateRandomString(n: number): string { * @param seed A seed to randomize the result * @returns An hexadecimal string representation of the hashed input */ -function cyrb53(str: string, seed = 0): string { +export function cyrb53(str: string, seed = 0): string { let h1 = 0xdeadbeef ^ seed; let h2 = 0x41c6ce57 ^ seed; for (let i = 0, ch; i < str.length; i++) { @@ -108,23 +109,19 @@ function cyrb53(str: string, seed = 0): string { return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16); } -function capitalizeFirstLetter(s: string): string { +export function capitalizeFirstLetter(s: string): string { return s.charAt(0).toUpperCase() + s.slice(1); } -function capitalizeEachWord(s: string): string { +export function capitalizeEachWord(s: string): string { return s .split(" ") .map((word) => capitalizeFirstLetter(word)) .join(" "); } -export { - convertTimeMsToTimeElapsedString, - longestCommonStart, - containsAllStrings, - generateRandomString, - cyrb53, - capitalizeFirstLetter, - capitalizeEachWord, -}; +export function getNsApiDocumentationUrl(isDevBranch = CONSTANTS.isDevBranch): string { + return `https://github.com/bitburner-official/bitburner-src/blob/${ + isDevBranch ? "dev" : "stable" + }/markdown/bitburner.ns.md`; +}