import MarkdownIt from "markdown-it";
import type { MentionMap } from "./mentions";
import type { MarkdownIt as MarkdownRenderer, StateCore } from "markdown-it";
import { highlight } from "sugar-high";
import { FilterXSS, friendlyAttrValue, safeAttrValue } from "xss";
import { linkTextReferences } from "./references";
import { camoUrl, isOwnHost } from "./camo-sign";
import { userContentOriginFor } from "./usercontent-origin";
import { env } from "cloudflare:workers";
export type MarkdownContext = {
owner: string;
repo: string;
ref: string;
/** Directory of the document inside the repo, used to resolve relative links. */
basePath: string;
};
const ATTACHMENT_PREFIX = "/attachments/";
const ABSOLUTE_URL = /^(?:[a-z][a-z0-9+.-]*:|\/\/|#)/i;
/** GitHub's prefix for user-supplied ids/anchors, so content cannot clobber `window.<id>` or app anchors. */
const USER_CONTENT_PREFIX = "user-content-";
const LOCAL_BASES = ["https://local.invalid/", "http://local.invalid/"];
/**
* Parsed like a browser would against an https and an http page, so `//host`, `http:host` (on https) and
* `https:host` (on http) all count as leaving the page's origin.
*/
function isExternalUrl(value: string): boolean {
return LOCAL_BASES.some((base) => {
try {
return new URL(value.trim(), base).hostname !== "local.invalid";
} catch {
return false;
}
});
}
function externalHref(value: string): string {
for (const base of LOCAL_BASES) {