Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs] Fix async function anchors #13226

Merged
merged 2 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion docs/js/convert-old-anchorid.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ window.addEventListener('DOMContentLoaded', () => {

// only operate on the old id's
if (!/^#\w+_\w+(?:-\w+)?$/i.test(anchor)) {
return;
return fixNoAsyncFn();
}

// in case there is no anchor, return without modifying the anchor
Expand Down Expand Up @@ -68,4 +68,25 @@ window.addEventListener('DOMContentLoaded', () => {
window.location.hash = `#${test}`;
}
}

// function to fix dox not recognizing async functions and resulting in inproper anchors
function fixNoAsyncFn() {
const anchorSlice = anchor.slice(1);
// dont modify anchor if it already exists
if (document.querySelector(`h3[id="${anchorSlice}"`)) {
return;
}

const tests = [
`${anchorSlice}()`
];

for (const test of tests) {
// have to use the "[id=]" selector because "#Something()" is not a valid selector (the "()" part)
const header = document.querySelector(`h3[id="${test}"]`);
if (header) {
window.location.hash = `#${test}`;
}
}
}
}, { once: true });
47 changes: 47 additions & 0 deletions docs/source/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,53 @@ const files = [

const out = module.exports.docs = [];

// add custom matchers to dox, to recognize things it does not know about
// see https://github.com/tj/dox/issues/198
{
// Some matchers need to be in a specific order, like the "prototype" matcher must be before the static matcher (and inverted because "unshift")

// "unshift" is used, because the first function to return a object from "contextPatternMatchers" is used (and we need to "overwrite" those specific functions)

// push a matcher to recognize "Class.fn = async function" as a method
dox.contextPatternMatchers.unshift(function(str) {
const match = /^\s*([\w$.]+)\s*\.\s*([\w$]+)\s*=\s*(?:async\s+)?function/.exec(str);
if (match) {
return {
type: 'method',
receiver: match[1],
name: match[2],
string: match[1] + '.' + match[2] + '()'
};
}
});

// push a matcher to recognize "Class.prototype.fn = async function" as a method
dox.contextPatternMatchers.unshift(function(str) {
const match = /^\s*([\w$.]+)\s*\.\s*prototype\s*\.\s*([\w$]+)\s*=\s*(?:async\s+)?function/.exec(str);
if (match) {
return {
type: 'method',
constructor: match[1],
cons: match[1],
name: match[2],
string: match[1] + '.prototype.' + match[2] + '()'
};
}
});

// push a matcher to recognize "async function" as a function
dox.contextPatternMatchers.unshift(function(str) {
const match = /^\s*(export(\s+default)?\s+)?(?:async\s+)?function\s+([\w$]+)\s*\(/.exec(str);
if (match) {
return {
type: 'function',
name: match[3],
string: match[3] + '()'
};
}
});
}

const combinedFiles = [];
for (const file of files) {
try {
Expand Down