Merge remote-tracking branch 'upstream/main' into main

This commit is contained in:
Ed Rivas 2023-05-19 16:04:26 +00:00
commit 0dd7ca69b5
5 changed files with 1298 additions and 2487 deletions

View File

@ -12,7 +12,6 @@
'vendor/jquery-ui-custom/jquery-ui-theme',
'vendor/typedoc/style',
'vendor/typedoc/highlight',
'vendor/typedoc/icons',
'functions',
'breakpoints',

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,19 +10,6 @@ function bind(fn, first) {
}
class SassSiteRenderContext extends DefaultThemeRenderContext {
// Link to the external documentation of external APIs. Unfortunately, there's
// no way to use `addUnknownSymbolResolver` for names that don't come from npm
// packages.
attemptExternalResolution = function (symbol) {
if (symbol.escapedName === 'URL') {
return 'https://developer.mozilla.org/en-US/docs/Web/API/URL';
} else if (symbol.escapedName === 'Buffer') {
return 'https://nodejs.org/api/buffer.html';
} else {
return null;
}
};
// We don't include Typedoc's JS, so the default means of displaying overloads
// as multiple togglable definitions within a single member documentation
// doesn't work. Instead, we emit each overload as a separate entry with its
@ -46,118 +33,30 @@ class SassSiteRenderContext extends DefaultThemeRenderContext {
return context.oldMember(props);
}, this);
// Make categories visible in the sidebar as well as in the main page's index.
// Hopefully this will no longer be necessary once TypeStrong/typedoc#1532 is
// implemented.
oldNavigation = this.navigation;
navigation = bind(function (context, props) {
const navigation = context.oldNavigation(props);
const childrenByCategories = context._groupByCategory(props.model);
if (childrenByCategories.size === 0) return navigation;
const secondary = context._getNthChild(navigation, 1);
if (!secondary) return navigation;
const firstLI = context._getNthChild(context._getNthChild(secondary, 0), 0);
const ul = firstLI.props['class'].startsWith('current ')
? context._getNthChild(firstLI, 1)
: context._getNthChild(secondary, 0);
ul.children = Array.from(childrenByCategories).map(([title, children]) =>
JSX.createElement(
JSX.Fragment,
null,
JSX.createElement(
'li',
{ class: 'sl-tsd-category-label' },
JSX.createElement('span', null, title),
),
...children.map((child) =>
JSX.createElement(
'li',
{ class: child.cssClasses },
JSX.createElement(
'a',
{
href: context.urlTo(child),
class: 'tsd-kind-icon',
},
child.name,
),
),
),
),
);
return navigation;
}, this);
// Returns the `n`-th child of a JSX node. For some reason, JSX nodes created
// by TypeDoc can contain nested arrays, so this traverses them.
_getNthChild = (node, n) => {
let i = 0;
function traverse(array) {
for (const element of array) {
if (element instanceof Array) {
const result = traverse(element);
if (result != undefined) return result;
} else {
if (i === n) return element;
i++;
}
}
}
return traverse(node.children);
};
// Returns a map from category titles to the set of members of those
// categories.
_groupByCategory = (model) => {
const map = new Map();
function addCategoriesToMap(categories) {
for (const category of categories) {
const children = map.get(category.title);
if (children) {
children.push(...category.children);
} else {
map.set(category.title, [...category.children]);
}
}
}
if (model.categories) {
addCategoriesToMap(model.categories);
} else if (model.groups) {
for (const group of model.groups) {
if (group.categories) addCategoriesToMap(group.categories);
}
}
return map;
};
// Add compatibility indicators to the beginning of documentation blocks.
oldComment = this.comment;
comment = bind((context, props) => {
const compatibilityTags = props.comment?.tags.filter(
(tag) => tag.tagName === 'compatibility',
if (!props.comment) return;
const compatibilityTags = props.comment.blockTags.filter(
(tag) => tag.tag === '@compatibility',
);
props.comment?.removeTags('compatibility');
props.comment.removeTags('@compatibility');
const parent = this.oldComment(props);
if (!parent) return;
parent.children.unshift(
...compatibilityTags.map((compat) => {
// Compatibility tags should have a single text block.
const text = compat.content[0].text;
// The first line is arguments to impl_status, anything after that is the
// contents of the block.
const lineBreak = compat.text.indexOf('\n');
const lineBreak = text.indexOf('\n');
const firstLine =
lineBreak === -1 ? compat.text : compat.text.substring(0, lineBreak);
lineBreak === -1 ? text : text.substring(0, lineBreak);
const rest =
lineBreak === -1 ? null : compat.text.substring(lineBreak + 1).trim();
lineBreak === -1 ? null : text.substring(lineBreak + 1).trim();
return JSX.createElement(JSX.Raw, {
html:
@ -188,46 +87,36 @@ class SassSiteRenderContext extends DefaultThemeRenderContext {
),
this,
);
}
class SassSiteTheme extends DefaultTheme {
constructor(renderer) {
super(renderer);
// This is an ugly monkeypatch but it's necessary to work around
// TypeStrong/typedoc#1731.
//
// Relative URLs don't work well for index pages since they can be rendered at
// different directory levels, so we just convert all URLs to absolute to be
// safe.
const ContextAwareRendererComponent = Object.getPrototypeOf(
this.markedPlugin.constructor,
);
const oldGetRelativeUrl =
ContextAwareRendererComponent.prototype.getRelativeUrl;
ContextAwareRendererComponent.prototype.getRelativeUrl = function (url) {
const relative = oldGetRelativeUrl.call(this, url);
oldUrlTo = this.urlTo;
urlTo = bind(function (context, reflection) {
const relative = context.oldUrlTo(reflection);
const absolute = new URL(
relative,
`relative:///documentation/js-api/${this.location}`,
`relative:///documentation/js-api/${context.theme.markedPlugin.location}`,
);
absolute.pathname = absolute.pathname
.replace(/\.html$/, '')
.replace(/\/index$/, '');
return absolute.toString().replace(/^relative:\/\//, '');
};
}
}, this);
}
getRenderContext() {
class SassSiteTheme extends DefaultTheme {
getRenderContext(page) {
this.contextCache ??= new SassSiteRenderContext(
this,
page,
this.application.options,
);
return this.contextCache;
}
render(page) {
render(page, template) {
const context = this.getRenderContext(page);
// The default header includes a search bar that we don't want, so we just
@ -267,12 +156,12 @@ title: ${JSON.stringify(`${page.model.name} | JS API`)}
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
${JSX.renderElement(page.template(page))}
<div class="col-content">
${JSX.renderElement(template(page))}
</div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
${JSX.renderElement(context.navigation(page))}
<div class="col-sidebar">
<div class="site-menu">
${JSX.renderElement(context.sidebar(page))}
</div>
</div>
</div>
@ -294,14 +183,32 @@ title: ${JSON.stringify(`${page.model.name} | JS API`)}
// annotations as @-tags rather than needing to write out the HTML by hand.
exports.load = (app) => {
app.renderer.addUnknownSymbolResolver(
'immutable',
(name) => `https://immutable-js.com/docs/latest@main/${name}/`,
);
app.renderer.addUnknownSymbolResolver('source-map-js', (name) => {
app.converter.addUnknownSymbolResolver((ref, refl, part, symbolId) => {
if (!symbolId) return;
const name = symbolId.qualifiedName;
switch (ref.moduleSource) {
case 'immutable':
return `https://immutable-js.com/docs/latest@main/${name}/`;
case 'source-map-js':
if (name === 'RawSourceMap') {
return 'https://github.com/mozilla/source-map/blob/58819f09018d56ef84dc41ba9c93f554e0645169/source-map.d.ts#L15-L23';
}
case '@types/node':
if (name === 'Buffer') {
return 'https://nodejs.org/api/buffer.html';
}
break;
case 'typescript':
switch (name) {
case 'URL':
return 'https://developer.mozilla.org/en-US/docs/Web/API/URL';
case 'Promise':
return 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise';
}
break;
}
});
app.renderer.defineTheme('sass-site', SassSiteTheme);