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/jquery-ui-custom/jquery-ui-theme',
'vendor/typedoc/style', 'vendor/typedoc/style',
'vendor/typedoc/highlight', 'vendor/typedoc/highlight',
'vendor/typedoc/icons',
'functions', 'functions',
'breakpoints', '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 { 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 // We don't include Typedoc's JS, so the default means of displaying overloads
// as multiple togglable definitions within a single member documentation // as multiple togglable definitions within a single member documentation
// doesn't work. Instead, we emit each overload as a separate entry with its // 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); return context.oldMember(props);
}, this); }, 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. // Add compatibility indicators to the beginning of documentation blocks.
oldComment = this.comment; oldComment = this.comment;
comment = bind((context, props) => { comment = bind((context, props) => {
const compatibilityTags = props.comment?.tags.filter( if (!props.comment) return;
(tag) => tag.tagName === 'compatibility', const compatibilityTags = props.comment.blockTags.filter(
(tag) => tag.tag === '@compatibility',
); );
props.comment?.removeTags('compatibility'); props.comment.removeTags('@compatibility');
const parent = this.oldComment(props); const parent = this.oldComment(props);
if (!parent) return; if (!parent) return;
parent.children.unshift( parent.children.unshift(
...compatibilityTags.map((compat) => { ...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 // The first line is arguments to impl_status, anything after that is the
// contents of the block. // contents of the block.
const lineBreak = compat.text.indexOf('\n'); const lineBreak = text.indexOf('\n');
const firstLine = const firstLine =
lineBreak === -1 ? compat.text : compat.text.substring(0, lineBreak); lineBreak === -1 ? text : text.substring(0, lineBreak);
const rest = const rest =
lineBreak === -1 ? null : compat.text.substring(lineBreak + 1).trim(); lineBreak === -1 ? null : text.substring(lineBreak + 1).trim();
return JSX.createElement(JSX.Raw, { return JSX.createElement(JSX.Raw, {
html: html:
@ -188,46 +87,36 @@ class SassSiteRenderContext extends DefaultThemeRenderContext {
), ),
this, 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 // 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 // different directory levels, so we just convert all URLs to absolute to be
// safe. // safe.
const ContextAwareRendererComponent = Object.getPrototypeOf( oldUrlTo = this.urlTo;
this.markedPlugin.constructor, urlTo = bind(function (context, reflection) {
); const relative = context.oldUrlTo(reflection);
const oldGetRelativeUrl =
ContextAwareRendererComponent.prototype.getRelativeUrl;
ContextAwareRendererComponent.prototype.getRelativeUrl = function (url) {
const relative = oldGetRelativeUrl.call(this, url);
const absolute = new URL( const absolute = new URL(
relative, relative,
`relative:///documentation/js-api/${this.location}`, `relative:///documentation/js-api/${context.theme.markedPlugin.location}`,
); );
absolute.pathname = absolute.pathname absolute.pathname = absolute.pathname
.replace(/\.html$/, '') .replace(/\.html$/, '')
.replace(/\/index$/, ''); .replace(/\/index$/, '');
return absolute.toString().replace(/^relative:\/\//, ''); return absolute.toString().replace(/^relative:\/\//, '');
}; }, this);
} }
getRenderContext() { class SassSiteTheme extends DefaultTheme {
getRenderContext(page) {
this.contextCache ??= new SassSiteRenderContext( this.contextCache ??= new SassSiteRenderContext(
this, this,
page,
this.application.options, this.application.options,
); );
return this.contextCache; return this.contextCache;
} }
render(page) { render(page, template) {
const context = this.getRenderContext(page); const context = this.getRenderContext(page);
// The default header includes a search bar that we don't want, so we just // 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> </header>
<div class="container container-main"> <div class="container container-main">
<div class="row"> <div class="col-content">
<div class="col-8 col-content"> ${JSX.renderElement(template(page))}
${JSX.renderElement(page.template(page))}
</div> </div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight"> <div class="col-sidebar">
${JSX.renderElement(context.navigation(page))} <div class="site-menu">
${JSX.renderElement(context.sidebar(page))}
</div> </div>
</div> </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. // annotations as @-tags rather than needing to write out the HTML by hand.
exports.load = (app) => { exports.load = (app) => {
app.renderer.addUnknownSymbolResolver( app.converter.addUnknownSymbolResolver((ref, refl, part, symbolId) => {
'immutable', if (!symbolId) return;
(name) => `https://immutable-js.com/docs/latest@main/${name}/`, const name = symbolId.qualifiedName;
);
app.renderer.addUnknownSymbolResolver('source-map-js', (name) => { switch (ref.moduleSource) {
case 'immutable':
return `https://immutable-js.com/docs/latest@main/${name}/`;
case 'source-map-js':
if (name === 'RawSourceMap') { if (name === 'RawSourceMap') {
return 'https://github.com/mozilla/source-map/blob/58819f09018d56ef84dc41ba9c93f554e0645169/source-map.d.ts#L15-L23'; 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); app.renderer.defineTheme('sass-site', SassSiteTheme);