diff --git a/docs/js/convert-old-anchorid.js b/docs/js/convert-old-anchorid.js index fd8054019c2..5f651092f6e 100644 --- a/docs/js/convert-old-anchorid.js +++ b/docs/js/convert-old-anchorid.js @@ -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 @@ -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 }); diff --git a/docs/source/api.js b/docs/source/api.js index 4eab51320fe..de6bfe2e0fe 100644 --- a/docs/source/api.js +++ b/docs/source/api.js @@ -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 {