diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 55a94e2..c4e21f6 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -64,7 +64,7 @@ module.exports = { description: meta.description, head, plugins: [ - require('./generateApiDocs/index'), + require('generateApiDocs'), ['@vuepress/google-analytics',{ga: isDeployPreview ? '' : 'UA-12818324-8',}], ['@vuepress/pwa', { serviceWorker: false, diff --git a/docs/.vuepress/generateApiDocs/clientDynamicModules.js b/docs/.vuepress/generateApiDocs/clientDynamicModules.js index 91dfd22..d09c4c0 100644 --- a/docs/.vuepress/generateApiDocs/clientDynamicModules.js +++ b/docs/.vuepress/generateApiDocs/clientDynamicModules.js @@ -1,4 +1,4 @@ -const generator = require('./utils/node/generator'); +const generator = require('./node/generator'); const {green} = require('chalk'); /** diff --git a/docs/.vuepress/generateApiDocs/debug.js b/docs/.vuepress/generateApiDocs/debug.js deleted file mode 100644 index 1c2005f..0000000 --- a/docs/.vuepress/generateApiDocs/debug.js +++ /dev/null @@ -1,10 +0,0 @@ -const getSlotDefinitions = require('./utils/node/getAdditionalSlotProperties'); -const generator = require('./utils/node/generator'); - -(async () => { - - const component = await generator('/Users/sagalbot/Sites/vue-select/docs'); - - debugger; - -})(); diff --git a/docs/.vuepress/generateApiDocs/extendPageData.js b/docs/.vuepress/generateApiDocs/extendPageData.js index 85f3dcc..c10a935 100644 --- a/docs/.vuepress/generateApiDocs/extendPageData.js +++ b/docs/.vuepress/generateApiDocs/extendPageData.js @@ -1,4 +1,4 @@ -const generator = require('./utils/node/generator'); +const generator = require('./node/generator'); module.exports = async function (page) { const section = ['props', 'events', 'slots', 'methods'].find( diff --git a/docs/.vuepress/generateApiDocs/node/Slots.js b/docs/.vuepress/generateApiDocs/node/Slots.js new file mode 100644 index 0000000..84ec243 --- /dev/null +++ b/docs/.vuepress/generateApiDocs/node/Slots.js @@ -0,0 +1,29 @@ +module.exports = class Slots { + constructor (slots = {}) { + this.slots = slots; + } + + add (name, slot) { + this.slots[name] = slot; + return this; + } + + get definitions () { + return this.slots; + } + + /** + * @return {*[]} + */ + get bindings () { + const normalizeBindings = bindings => { + return Object.values(bindings) + .map(binding => binding.replace(/ *\([^)]*\) */g, '')); + }; + + return Object + .values(this.slots) + .map(({bindings}) => normalizeBindings(bindings)) + .reduce((store, bindings) => [...store, ...bindings], []); + } +}; diff --git a/docs/.vuepress/generateApiDocs/node/debug.js b/docs/.vuepress/generateApiDocs/node/debug.js new file mode 100644 index 0000000..e3f0d2e --- /dev/null +++ b/docs/.vuepress/generateApiDocs/node/debug.js @@ -0,0 +1,10 @@ +const getSlotDefinitions = require('./getAdditionalSlotProperties'); +const generator = require('./generator'); + +(async () => { + + const component = await generator('/Users/sagalbot/Sites/vue-select/docs'); + + debugger; + +})(); diff --git a/docs/.vuepress/generateApiDocs/utils/node/generator.js b/docs/.vuepress/generateApiDocs/node/generator.js similarity index 100% rename from docs/.vuepress/generateApiDocs/utils/node/generator.js rename to docs/.vuepress/generateApiDocs/node/generator.js diff --git a/docs/.vuepress/generateApiDocs/utils/node/getAdditionalSlotProperties.js b/docs/.vuepress/generateApiDocs/node/getAdditionalSlotProperties.js similarity index 56% rename from docs/.vuepress/generateApiDocs/utils/node/getAdditionalSlotProperties.js rename to docs/.vuepress/generateApiDocs/node/getAdditionalSlotProperties.js index 85f1a9a..297ab8b 100644 --- a/docs/.vuepress/generateApiDocs/utils/node/getAdditionalSlotProperties.js +++ b/docs/.vuepress/generateApiDocs/node/getAdditionalSlotProperties.js @@ -18,6 +18,40 @@ function pickBindingsFromElement ({attribs}) { ); } +function parseDocBlock(comment) { + +} + +function findDocBlockForExpression(path, comments) { + const methodLocationStart = path.node.loc.start; + return comments.find(({loc}) => { + return methodLocationStart.line - 1 === loc.end.line; + }).value || ''; +} + +/** + * @param {Slots} slots + * @param content + */ +function getSlotBindingComments (slots, {content}) { + const ast = parse(content, {sourceType: 'module'}); + + /** + * TODO: + * - [ ] this traversal currently includes watchers, need to limit to + * props, methods, computed, maybe data too? + * - [ ] attach the comments to the bindings + */ + + traverse.default(ast, { + enter (path) { + if (path.node.key && slots.bindings.includes(path.node.key.name)) { + const comments = findDocBlockForExpression(path, ast.comments); + } + }, + }); +} + /** * @param pathToComponent * @return {Object} @@ -25,9 +59,10 @@ function pickBindingsFromElement ({attribs}) { function getAdditionalSlotProperties (pathToComponent) { const slots = new Slots(); const file = fs.readFileSync(path.resolve(pathToComponent)).toString(); - const {template} = compiler.parseComponent(file); + const {template, script} = compiler.parseComponent(file); const $ = cheerio.load(template.content); + $('slot').each(function (index, element) { const bindings = pickBindingsFromElement(element) || {}; const slotName = element.attribs.name || 'default'; @@ -39,6 +74,8 @@ function getAdditionalSlotProperties (pathToComponent) { }); }); + getSlotBindingComments(slots, script); + return slots.definitions; } diff --git a/docs/.vuepress/generateApiDocs/utils/node/getMixins.js b/docs/.vuepress/generateApiDocs/node/getMixins.js similarity index 100% rename from docs/.vuepress/generateApiDocs/utils/node/getMixins.js rename to docs/.vuepress/generateApiDocs/node/getMixins.js diff --git a/docs/.vuepress/generateApiDocs/package.json b/docs/.vuepress/generateApiDocs/package.json new file mode 100644 index 0000000..b51766c --- /dev/null +++ b/docs/.vuepress/generateApiDocs/package.json @@ -0,0 +1,19 @@ +{ + "name": "generateapidocs", + "version": "0.1.0", + "description": "Generates API documentation for Vue components.", + "main": "index.js", + "module": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "Vue", + "DocGen", + "JSDoc", + "Component", + "Documentation" + ], + "author": "Jeff Sagal", + "license": "MIT" +} diff --git a/docs/.vuepress/generateApiDocs/utils/node/Slots.js b/docs/.vuepress/generateApiDocs/utils/node/Slots.js deleted file mode 100644 index f4a2561..0000000 --- a/docs/.vuepress/generateApiDocs/utils/node/Slots.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = class Slots { - constructor (slots = {}) { - this.slots = slots; - } - - add (name, slot) { - this.slots[name] = slot; - return this; - } - - get definitions () { - return this.slots; - } - - absorb (slots) { - this.slots.map() - } -}; diff --git a/docs/package.json b/docs/package.json index 6c155c8..72ecf71 100644 --- a/docs/package.json +++ b/docs/package.json @@ -21,6 +21,7 @@ "cheerio": "^1.0.0-rc.3", "cross-env": "^5.2.0", "fuse.js": "^3.4.4", + "generateapidocs": "/Users/sagalbot/Sites/vue-select/docs/.vuepress/generateApiDocs", "gh-pages": "^0.11.0", "lodash": "^4.17.15", "markdown-it": "^10.0.0", diff --git a/docs/yarn.lock b/docs/yarn.lock index 9974979..59fadba 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3576,6 +3576,9 @@ gaze@^1.0.0: dependencies: globule "^1.0.0" +generateapidocs@/Users/sagalbot/Sites/vue-select/docs/.vuepress/generateApiDocs: + version "0.1.0" + get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"