From 3114fa48621b057d28e79ab72858b4b81d7d68ba Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Fri, 9 Feb 2018 10:22:41 +0000 Subject: [PATCH] [ADF-1769] Added support for methods to JSDoc tool (#2925) * [ADF-1769] Refactored component props features * [ADF-1769] Added methods list feature to doc tool * [ADF-1769] Added support for optional parameters and initialisers * [ADF-1769] Switched off prop generator tool --- docs/content-node-dialog.service.md | 49 +- lib/config/DocProcessor/tools/tscProps.js | 334 ++++++++----- lib/config/DocProcessor/tools/tscProps.ts | 437 ++++++++++++------ lib/config/DocProcessor/unistHelpers.js | 6 + .../content-node-dialog.service.ts | 20 + 5 files changed, 587 insertions(+), 259 deletions(-) diff --git a/docs/content-node-dialog.service.md b/docs/content-node-dialog.service.md index edb0a17451..66c2776b7a 100644 --- a/docs/content-node-dialog.service.md +++ b/docs/content-node-dialog.service.md @@ -4,29 +4,38 @@ Displays and manages dialogs for selecting content to open, copy or upload. ## Methods -`openFileBrowseDialogByFolderId(folderNodeId: string): Observable`
-Opens a file browser at a chosen folder location. +- `openFileBrowseDialogByFolderId(folderNodeId: string): Observable` + Opens a file browser at a chosen folder location. + - `folderNodeId` - ID of the folder to use +- `openFileBrowseDialogBySite(): Observable` + Opens a file browser at a chosen site location. -`openFolderBrowseDialogByFolderId(folderNodeId: string): Observable`
-Opens a folder browser at a chosen folder location. +- `openFolderBrowseDialogBySite(): Observable` + Opens a folder browser at a chosen site location. -`openFileBrowseDialogBySite(): Observable`
-Opens a file browser at a chosen site location. +- `openFolderBrowseDialogByFolderId(folderNodeId: string): Observable` + Opens a folder browser at a chosen folder location. + - `folderNodeId` - ID of the folder to use +- `openCopyMoveDialog(action: string, contentEntry: MinimalNodeEntryEntity, permission?: string): Observable` + Opens a dialog to copy or move an item to a new location. + - `action` - Name of the action (eg, "Copy" or "Move") to show in the title + - `contentEntry` - Item to be copied or moved + - `permission` - (Optional) Permission for the operation +- `getTitleTranslation(action: string, name: string): string` + Gets the translation of the dialog title. + - `action` - Name of the action to display in the dialog title + - `name` - Name of the item on which the action is being performed +- `openUploadFolderDialog(action: string, contentEntry: MinimalNodeEntryEntity): Observable` + Opens a dialog to choose a folder to upload. + - `action` - Name of the action to show in the title + - `contentEntry` - Item to upload +- `openUploadFileDialog(action: string, contentEntry: MinimalNodeEntryEntity): Observable` + Opens a dialog to choose a file to upload. + - `action` - Name of the action to show in the title + - `contentEntry` - Item to upload +- `close()` + Closes the currently open dialog. -`openFolderBrowseDialogBySite(): Observable`
-Opens a folder browser at a chosen site location. - -`openCopyMoveDialog(action: string, contentEntry: MinimalNodeEntryEntity, permission?: string): Observable`
-Opens a dialog to copy or move an item to a new location. - -`openUploadFileDialog(action: string, contentEntry: MinimalNodeEntryEntity): Observable`
-Opens a dialog to choose a file to upload. - -`openUploadFolderDialog(action: string, contentEntry: MinimalNodeEntryEntity): Observable`
-Opens a dialog to choose a folder to upload. - -`close()`
-Closes the currently open dialog. ## Details diff --git a/lib/config/DocProcessor/tools/tscProps.js b/lib/config/DocProcessor/tools/tscProps.js index ee2e277cc8..3505ab5736 100644 --- a/lib/config/DocProcessor/tools/tscProps.js +++ b/lib/config/DocProcessor/tools/tscProps.js @@ -15,28 +15,183 @@ exports.readPhase = readPhase; function aggPhase(aggData) { } exports.aggPhase = aggPhase; +var PropData = /** @class */ (function () { + function PropData() { + } + return PropData; +}()); +var ParamData = /** @class */ (function () { + function ParamData() { + } + ParamData.prototype.getSignature = function () { + var sig = this.name; + if (this.optional) + sig += "?"; + sig += ": " + this.type; + if (this.initializer) + sig += " = " + this.initializer; + return sig; + }; + return ParamData; +}()); +var MethodData = /** @class */ (function () { + function MethodData() { + this.params = []; + } + MethodData.prototype.getSignature = function () { + var sig = this.name + "("; + if (this.params.length > 0) { + sig += this.params[0].getSignature(); + } + for (var i = 1; i < this.params.length; i++) { + sig += ", " + this.params[i].getSignature(); + } + sig += ")"; + if (this.returnType !== "void") { + sig += ": " + this.returnType; + } + return sig; + }; + return MethodData; +}()); +var ComponentDocAutoContent = /** @class */ (function () { + function ComponentDocAutoContent() { + this.inputs = []; + this.outputs = []; + } + ComponentDocAutoContent.prototype.extractClassInfoFromSource = function (checker, classDec) { + var sourceFile = classDec.getSourceFile(); + for (var i = 0; i < classDec.members.length; i++) { + var member = classDec.members[i]; + if (ts.isPropertyDeclaration(member) || + ts.isGetAccessorDeclaration(member) || + ts.isSetAccessorDeclaration(member)) { + var prop = member; + var mods = ts.getCombinedModifierFlags(prop); + var nonPrivate = (mods & ts.ModifierFlags.Private) === 0; + var memSymbol = checker.getSymbolAtLocation(prop.name); + if (nonPrivate && memSymbol && prop.decorators) { + var name_1 = memSymbol.getName(); + var initializer = ""; + if (prop.initializer) { + initializer = prop.initializer.getText(sourceFile); + } + var doc = ts.displayPartsToString(memSymbol.getDocumentationComment(checker)); + doc = doc.replace(/\r\n/g, " "); + var propType = checker.typeToString(checker.getTypeOfSymbolAtLocation(memSymbol, memSymbol.valueDeclaration)); + var dec = prop.decorators[0].getText(sourceFile); + if (dec.match(/@Input/)) { + this.inputs.push({ + "name": name_1, + "type": propType, + "initializer": initializer, + "docText": doc + }); + } + else if (dec.match(/@Output/)) { + this.outputs.push({ + "name": name_1, + "type": propType, + "initializer": "", + "docText": doc + }); + } + } + } + } + }; + ComponentDocAutoContent.prototype.addContentToDoc = function (tree) { + var inTable = buildPropsTable(this.inputs); + var outTable = buildPropsTable(this.outputs, false); + if (inTable) { + heading(tree, "Properties", function (before, section, after) { + return [before, inTable, after]; + }); + } + if (outTable) { + heading(tree, "Events", function (before, section, after) { + return [before, outTable, after]; + }); + } + }; + return ComponentDocAutoContent; +}()); +var ServiceDocAutoContent = /** @class */ (function () { + function ServiceDocAutoContent() { + this.props = []; + this.methods = []; + } + ServiceDocAutoContent.prototype.extractClassInfoFromSource = function (checker, classDec) { + var sourceFile = classDec.getSourceFile(); + for (var i = 0; i < classDec.members.length; i++) { + var member = classDec.members[i]; + if (ts.isMethodDeclaration(member)) { + var method = member; + var mods = ts.getCombinedModifierFlags(method); + var nonPrivate = (mods & ts.ModifierFlags.Private) === 0; + var memSymbol = checker.getSymbolAtLocation(method.name); + if (nonPrivate && memSymbol) { + var methData = new MethodData(); + methData.name = memSymbol.getName(); + var doc = ts.displayPartsToString(memSymbol.getDocumentationComment()); + methData.docText = doc.replace(/\r\n/g, " "); + var sig = checker.getSignatureFromDeclaration(method); + var returnType = sig.getReturnType(); + methData.returnType = checker.typeToString(returnType); + var returnSymbol = returnType.getSymbol(); + var params = method.parameters; + for (var p = 0; p < params.length; p++) { + var pData = new ParamData(); + pData.name = params[p].name.getText(); + pData.type = params[p].type.getText(); + var paramSymbol = checker.getSymbolAtLocation(params[p].name); + pData.docText = ts.displayPartsToString(paramSymbol.getDocumentationComment()); + pData.optional = params[p].questionToken ? true : false; + if (params[p].initializer) { + var initText = params[p].initializer.getText(); + if (initText !== "undefined") + pData.initializer = initText; + } + methData.params.push(pData); + } + this.methods.push(methData); + } + } + } + }; + ServiceDocAutoContent.prototype.addContentToDoc = function (tree) { + var propsTable = buildPropsTable(this.props); + var methodsList = buildMethodsList(this.methods); + if (propsTable) { + heading(tree, "Properties", function (before, section, after) { + return [before, propsTable, after]; + }); + } + if (methodsList) { + heading(tree, "Methods", function (before, section, after) { + return [before, methodsList, after]; + }); + } + }; + return ServiceDocAutoContent; +}()); function updatePhase(tree, pathname, aggData) { var fileNameNoSuffix = path.basename(pathname, ".md"); - if (fileNameNoSuffix.match(/component/)) { + var itemType = fileNameNoSuffix.match(/component|service/); + if (itemType) { var srcData = aggData.srcData[fileNameNoSuffix]; if (srcData) { var srcPath = srcData.path; - var className = fixCompodocFilename(fileNameNoSuffix); - var inputs = []; - var outputs = []; - getPropDocData(path.resolve(".", srcPath), className, inputs, outputs); - var inTable_1 = buildInputsTable(inputs); - var outTable_1 = buildOutputsTable(outputs); - if (inTable_1) { - heading(tree, "Properties", function (before, section, after) { - return [before, inTable_1, after]; - }); + var className = fixAngularFilename(fileNameNoSuffix); + var classData = void 0; + if (itemType[0] === "component") { + classData = new ComponentDocAutoContent(); } - if (outTable_1) { - heading(tree, "Events", function (before, section, after) { - return [before, outTable_1, after]; - }); + else if (itemType[0] === "service") { + classData = new ServiceDocAutoContent(); } + getDocSourceData(path.resolve(".", srcPath), className, classData); + classData.addContentToDoc(tree); } return true; } @@ -48,7 +203,7 @@ exports.updatePhase = updatePhase; function initialCap(str) { return str[0].toUpperCase() + str.substr(1); } -function fixCompodocFilename(rawName) { +function fixAngularFilename(rawName) { var name = rawName.replace(/\]|\(|\)/g, ''); var fileNameSections = name.split('.'); var compNameSections = fileNameSections[0].split('-'); @@ -63,7 +218,7 @@ function fixCompodocFilename(rawName) { var finalName = outCompName + itemTypeIndicator; return finalName; } -function getPropDocData(srcPath, docClassName, inputs, outputs) { +function getDocSourceData(srcPath, docClassName, classData) { var prog = ts.createProgram([srcPath], { target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS }); @@ -80,15 +235,15 @@ function getPropDocData(srcPath, docClassName, inputs, outputs) { var classDec = node; var sourceFile = classDec.getSourceFile(); if (classDec.name.escapedText === docClassName) { - getPropDataFromClassChain(checker, classDec, inputs, outputs); + getPropDataFromClassChain(checker, classDec, classData); } } } } // Get properties/events from main class and all inherited classes. -function getPropDataFromClassChain(checker, classDec, inputs, outputs) { +function getPropDataFromClassChain(checker, classDec, classData) { // Main class - getPropDataFromClass(checker, classDec, inputs, outputs); + classData.extractClassInfoFromSource(checker, classDec); // Inherited classes if (classDec.heritageClauses) { for (var _i = 0, _a = classDec.heritageClauses; _i < _a.length; _i++) { @@ -97,81 +252,38 @@ function getPropDataFromClassChain(checker, classDec, inputs, outputs) { for (var _b = 0, _c = hcType.symbol.declarations; _b < _c.length; _b++) { var dec = _c[_b]; if (typescript_1.isClassDeclaration(dec)) { - getPropDataFromClassChain(checker, dec, inputs, outputs); + getPropDataFromClassChain(checker, dec, classData); } } } } } -function getPropDataFromClass(checker, classDec, inputs, outputs) { - var sourceFile = classDec.getSourceFile(); - for (var i = 0; i < classDec.members.length; i++) { - var member = classDec.members[i]; - if (ts.isPropertyDeclaration(member) || - ts.isGetAccessorDeclaration(member) || - ts.isSetAccessorDeclaration(member)) { - var prop = member; - var mods = ts.getCombinedModifierFlags(prop); - var nonPrivate = (mods & ts.ModifierFlags.Private) === 0; - var memSymbol = checker.getSymbolAtLocation(prop.name); - if (nonPrivate && memSymbol && prop.decorators) { - var name_1 = memSymbol.getName(); - var initializer = ""; - if (prop.initializer) { - initializer = prop.initializer.getText(sourceFile); - } - var doc = ts.displayPartsToString(memSymbol.getDocumentationComment(checker)); - doc = doc.replace(/\r\n/g, " "); - var propType = checker.typeToString(checker.getTypeOfSymbolAtLocation(memSymbol, memSymbol.valueDeclaration)); - var dec = prop.decorators[0].getText(sourceFile); - if (dec.match(/@Input/)) { - inputs.push({ - "name": name_1, - "type": propType, - "init": initializer, - "docText": doc - }); - } - else if (dec.match(/@Output/)) { - outputs.push({ - "name": name_1, - "type": propType, - "docText": doc - }); - } - } - } - } -} -function buildInputsTable(inputs) { - if (inputs.length === 0) { +function buildPropsTable(props, includeInitializer) { + if (includeInitializer === void 0) { includeInitializer = true; } + if (props.length === 0) { return null; } - var rows = [ - unist.makeTableRow([ - unist.makeTableCell([unist.makeText("Name")]), - unist.makeTableCell([unist.makeText("Type")]), - unist.makeTableCell([unist.makeText("Default value")]), - unist.makeTableCell([unist.makeText("Description")]) - ]) + var headerCells = [ + unist.makeTableCell([unist.makeText("Name")]), + unist.makeTableCell([unist.makeText("Type")]) ]; - for (var i = 0; i < inputs.length; i++) { - var pName = inputs[i].name; - var pType = inputs[i].type; - var pDefault = inputs[i].init || ""; - var pDesc = inputs[i].docText || ""; + if (includeInitializer) + headerCells.push(unist.makeTableCell([unist.makeText("Default value")])); + headerCells.push(unist.makeTableCell([unist.makeText("Description")])); + var rows = [ + unist.makeTableRow(headerCells) + ]; + for (var i = 0; i < props.length; i++) { + var pName = props[i].name; + var pType = props[i].type; + var pDefault = props[i].initializer || ""; + var pDesc = props[i].docText || ""; if (pDesc) { - //pDesc = pDesc.trim().replace(/[\n\r]+/, " "); pDesc = pDesc.replace(/[\n\r]+/, " "); } var descCellContent = remark().parse(pDesc).children; var defaultCellContent; if (pDefault) { - /* - descCellContent.push(unist.makeHTML("
")); - descCellContent.push(unist.makeText(" Default value: ")); - descCellContent.push(unist.makeInlineCode(pDefault)); - */ defaultCellContent = unist.makeInlineCode(pDefault); } else { @@ -179,41 +291,45 @@ function buildInputsTable(inputs) { } var cells = [ unist.makeTableCell([unist.makeText(pName)]), - unist.makeTableCell([unist.makeInlineCode(pType)]), - //unist.makeTableCell([unist.makeInlineCode(pDefault)]), - unist.makeTableCell([defaultCellContent]), - unist.makeTableCell(descCellContent) + unist.makeTableCell([unist.makeInlineCode(pType)]) ]; + if (includeInitializer) + cells.push(unist.makeTableCell([defaultCellContent])); + cells.push(unist.makeTableCell(descCellContent)); rows.push(unist.makeTableRow(cells)); } - return unist.makeTable([null, null, null, null], rows); + var spacers = [null, null, null]; + if (includeInitializer) + spacers.push(null); + return unist.makeTable(spacers, rows); } -function buildOutputsTable(outputs) { - if (outputs.length === 0) { +function buildMethodsList(methods) { + if (methods.length === 0) return null; - } - var rows = [ - unist.makeTableRow([ - unist.makeTableCell([unist.makeText("Name")]), - unist.makeTableCell([unist.makeText("Type")]), - unist.makeTableCell([unist.makeText("Description")]) - ]) - ]; - for (var i = 0; i < outputs.length; i++) { - var eName = outputs[i].name; - var eType = outputs[i].type; - var eDesc = outputs[i].docText || ""; - if (eDesc) { - eDesc = eDesc.trim().replace(/[\n\r]+/, ' '); + var listItems = []; + for (var _i = 0, methods_1 = methods; _i < methods_1.length; _i++) { + var method = methods_1[_i]; + var itemLines = []; + itemLines.push(unist.makeInlineCode(method.getSignature())); + itemLines.push(unist.makeBreak()); + itemLines.push(unist.makeParagraph(remark().parse(method.docText).children)); + itemLines.push(unist.makeBreak()); + var paramListItems = []; + for (var _a = 0, _b = method.params; _a < _b.length; _a++) { + var param = _b[_a]; + var currParamSections = []; + if (param.docText !== "") { + currParamSections.push(unist.makeInlineCode(param.name)); + var optionalPart = param.optional ? "(Optional) " : ""; + currParamSections.push(unist.makeText(" - " + optionalPart + param.docText)); + //currParamSections.push(unist.makeBreak()); + paramListItems.push(unist.makeListItem(unist.makeParagraph(currParamSections))); + } } - var cells = [ - unist.makeTableCell([unist.makeText(eName)]), - unist.makeTableCell([unist.makeInlineCode(eType)]), - unist.makeTableCell(remark().parse(eDesc).children) - ]; - rows.push(unist.makeTableRow(cells)); + itemLines.push(unist.makeListUnordered(paramListItems)); + listItems.push(unist.makeListItem(unist.makeParagraph(itemLines))); } - return unist.makeTable([null, null, null], rows); + return unist.makeListUnordered(listItems); } function isNodeExported(node) { return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 || (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile); diff --git a/lib/config/DocProcessor/tools/tscProps.ts b/lib/config/DocProcessor/tools/tscProps.ts index 36da724e50..d9a1057eac 100644 --- a/lib/config/DocProcessor/tools/tscProps.ts +++ b/lib/config/DocProcessor/tools/tscProps.ts @@ -7,7 +7,7 @@ import * as heading from "mdast-util-heading-range"; import * as remark from "remark"; import * as unist from "../unistHelpers"; -import { JsxEmit, isClassDeclaration } from "typescript"; +import { JsxEmit, isClassDeclaration, PropertyDeclaration } from "typescript"; export function initPhase(aggData) { } @@ -18,42 +18,263 @@ export function readPhase(tree, pathname, aggData) { export function aggPhase(aggData) { } + +interface NgDocAutoContent { + extractClassInfoFromSource(checker: ts.TypeChecker, classDec: ts.ClassDeclaration); + addContentToDoc(tree); +} + +class PropData { + name: string; + type: string; + initializer: string; + docText: string; +} + +class ParamData { + name: string; + type: string; + docText: string; + initializer: string; + optional: boolean; + + getSignature() { + let sig =this.name; + + if (this.optional) + sig += "?"; + + sig += ": " + this.type; + + if (this.initializer) + sig += " = " + this.initializer; + + return sig; + } +} + +class MethodData { + name: string; + docText: string; + params: ParamData[]; + returnType: string; + + constructor() { + this.params = []; + } + + getSignature() { + let sig = this.name + "("; + + if (this.params.length > 0) { + sig += this.params[0].getSignature(); + } + + for (let i = 1; i < this.params.length; i++) { + sig += ", " + this.params[i].getSignature(); + } + + sig += ")"; + + if (this.returnType !== "void") { + sig += ": " + this.returnType; + } + + return sig; + } +} + +class ComponentDocAutoContent implements NgDocAutoContent { + inputs: PropData[]; + outputs: PropData[]; + + constructor() { + this.inputs = []; + this.outputs = []; + } + + + extractClassInfoFromSource(checker: ts.TypeChecker, classDec: ts.ClassDeclaration) { + let sourceFile = classDec.getSourceFile(); + + for (var i = 0; i < classDec.members.length; i++) { + let member = classDec.members[i]; + + if (ts.isPropertyDeclaration(member) || + ts.isGetAccessorDeclaration(member) || + ts.isSetAccessorDeclaration(member)) { + let prop: ts.PropertyDeclaration = member; + + let mods = ts.getCombinedModifierFlags(prop); + let nonPrivate = (mods & ts.ModifierFlags.Private) === 0; + let memSymbol = checker.getSymbolAtLocation(prop.name); + + if (nonPrivate && memSymbol && prop.decorators) { + let name = memSymbol.getName(); + let initializer = ""; + + if (prop.initializer) { + initializer = prop.initializer.getText(sourceFile); + } + + let doc = ts.displayPartsToString(memSymbol.getDocumentationComment(checker)); + doc = doc.replace(/\r\n/g, " "); + + let propType = checker.typeToString(checker.getTypeOfSymbolAtLocation(memSymbol, memSymbol.valueDeclaration!)); + + let dec = prop.decorators[0].getText(sourceFile); + + if (dec.match(/@Input/)) { + this.inputs.push({ + "name": name, + "type": propType, + "initializer": initializer, + "docText": doc + }); + } else if (dec.match(/@Output/)) { + this.outputs.push({ + "name": name, + "type": propType, + "initializer": "", + "docText": doc + }); + } + } + } + } + } + + + addContentToDoc(tree) { + let inTable = buildPropsTable(this.inputs); + let outTable = buildPropsTable(this.outputs, false); + + if (inTable) { + heading(tree, "Properties", (before, section, after) => { + return [before, inTable, after]; + }); + } + + if (outTable) { + heading(tree, "Events", (before, section, after) => { + return [before, outTable, after]; + }); + } + } +} + + +class ServiceDocAutoContent implements NgDocAutoContent { + props: PropData[]; + methods: MethodData[]; + + constructor() { + this.props = []; + this.methods = []; + } + + + extractClassInfoFromSource(checker: ts.TypeChecker, classDec: ts.ClassDeclaration) { + let sourceFile = classDec.getSourceFile(); + + for (var i = 0; i < classDec.members.length; i++) { + let member = classDec.members[i]; + + if (ts.isMethodDeclaration(member)) { + let method: ts.MethodDeclaration = member; + + let mods = ts.getCombinedModifierFlags(method); + let nonPrivate = (mods & ts.ModifierFlags.Private) === 0; + let memSymbol = checker.getSymbolAtLocation(method.name); + + if (nonPrivate && memSymbol) { + let methData = new MethodData(); + + methData.name = memSymbol.getName(); + let doc = ts.displayPartsToString(memSymbol.getDocumentationComment()); + methData.docText = doc.replace(/\r\n/g, " "); + let sig = checker.getSignatureFromDeclaration(method); + let returnType = sig.getReturnType(); + methData.returnType = checker.typeToString(returnType); + let returnSymbol = returnType.getSymbol(); + + let params = method.parameters; + + for (let p = 0; p < params.length; p++){ + let pData = new ParamData(); + pData.name = params[p].name.getText(); + pData.type = params[p].type.getText(); + let paramSymbol = checker.getSymbolAtLocation(params[p].name); + pData.docText = ts.displayPartsToString(paramSymbol.getDocumentationComment()); + pData.optional = params[p].questionToken ? true : false; + + if (params[p].initializer) { + let initText = params[p].initializer.getText(); + + if (initText !== "undefined") + pData.initializer = initText; + } + + methData.params.push(pData); + } + + this.methods.push(methData); + } + + } + + } + + } + + + addContentToDoc(tree) { + let propsTable = buildPropsTable(this.props); + let methodsList = buildMethodsList(this.methods); + + if (propsTable) { + heading(tree, "Properties", (before, section, after) => { + return [before, propsTable, after]; + }); + } + + if (methodsList) { + heading(tree, "Methods", (before, section, after) => { + return [before, methodsList, after]; + }); + } + } +} + + export function updatePhase(tree, pathname, aggData) { let fileNameNoSuffix = path.basename(pathname, ".md"); - if (fileNameNoSuffix.match(/component/)) { + let itemType = fileNameNoSuffix.match(/component|service/); + + if (itemType) { let srcData = aggData.srcData[fileNameNoSuffix]; if (srcData) { let srcPath = srcData.path; - let className = fixCompodocFilename(fileNameNoSuffix); + let className = fixAngularFilename(fileNameNoSuffix); - let inputs = []; - let outputs = []; - getPropDocData(path.resolve(".", srcPath), className, inputs, outputs); + let classData: NgDocAutoContent; - let inTable = buildInputsTable(inputs); - let outTable = buildOutputsTable(outputs); - - if (inTable) { - heading(tree, "Properties", (before, section, after) => { - return [before, inTable, after]; - }); + if (itemType[0] === "component") { + classData = new ComponentDocAutoContent(); + } else if (itemType[0] === "service") { + classData = new ServiceDocAutoContent(); } - if (outTable) { - heading(tree, "Events", (before, section, after) => { - return [before, outTable, after]; - }); - } + getDocSourceData(path.resolve(".", srcPath), className, classData); + classData.addContentToDoc(tree); } return true; } else { return false; } - - } @@ -62,7 +283,7 @@ function initialCap(str: string) { } -function fixCompodocFilename(rawName: string) { +function fixAngularFilename(rawName: string) { var name = rawName.replace(/\]|\(|\)/g, ''); var fileNameSections = name.split('.'); @@ -86,7 +307,7 @@ function fixCompodocFilename(rawName: string) { } -function getPropDocData(srcPath: string, docClassName: string, inputs: any[], outputs: any[]) { +function getDocSourceData(srcPath: string, docClassName: string, classData: NgDocAutoContent) { let prog = ts.createProgram([srcPath], { target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS }); @@ -108,7 +329,7 @@ function getPropDocData(srcPath: string, docClassName: string, inputs: any[], ou let sourceFile = classDec.getSourceFile(); if (classDec.name.escapedText === docClassName) { - getPropDataFromClassChain(checker, classDec, inputs, outputs); + getPropDataFromClassChain(checker, classDec, classData); } } } @@ -119,11 +340,10 @@ function getPropDocData(srcPath: string, docClassName: string, inputs: any[], ou function getPropDataFromClassChain( checker: ts.TypeChecker, classDec: ts.ClassDeclaration, - inputs: any[], - outputs: any[] + classData: NgDocAutoContent ){ // Main class - getPropDataFromClass(checker, classDec, inputs, outputs); + classData.extractClassInfoFromSource(checker, classDec); // Inherited classes if (classDec.heritageClauses) { @@ -132,7 +352,7 @@ function getPropDataFromClassChain( for (const dec of hcType.symbol.declarations) { if (isClassDeclaration(dec)) { - getPropDataFromClassChain(checker, dec, inputs, outputs); + getPropDataFromClassChain(checker, dec, classData); } } } @@ -141,83 +361,32 @@ function getPropDataFromClassChain( } -function getPropDataFromClass( - checker: ts.TypeChecker, - classDec: ts.ClassDeclaration, - inputs: any[], - outputs: any[] -){ - let sourceFile = classDec.getSourceFile(); - - for (var i = 0; i < classDec.members.length; i++) { - let member = classDec.members[i]; - - if (ts.isPropertyDeclaration(member) || - ts.isGetAccessorDeclaration(member) || - ts.isSetAccessorDeclaration(member)) { - let prop: ts.PropertyDeclaration = member; - - let mods = ts.getCombinedModifierFlags(prop); - let nonPrivate = (mods & ts.ModifierFlags.Private) === 0; - let memSymbol = checker.getSymbolAtLocation(prop.name); - - if (nonPrivate && memSymbol && prop.decorators) { - let name = memSymbol.getName(); - let initializer = ""; - - if (prop.initializer) { - initializer = prop.initializer.getText(sourceFile); - } - - let doc = ts.displayPartsToString(memSymbol.getDocumentationComment(checker)); - doc = doc.replace(/\r\n/g, " "); - - let propType = checker.typeToString(checker.getTypeOfSymbolAtLocation(memSymbol, memSymbol.valueDeclaration!)); - - let dec = prop.decorators[0].getText(sourceFile); - - if (dec.match(/@Input/)) { - inputs.push({ - "name": name, - "type": propType, - "init": initializer, - "docText": doc - }); - } else if (dec.match(/@Output/)) { - outputs.push({ - "name": name, - "type": propType, - "docText": doc - }); - } - } - } - } -} - - -function buildInputsTable(inputs: any[]) { - if (inputs.length === 0) { +function buildPropsTable(props: PropData[], includeInitializer: boolean = true) { + if (props.length === 0) { return null; } + var headerCells = [ + unist.makeTableCell([unist.makeText("Name")]), + unist.makeTableCell([unist.makeText("Type")]) + ]; + + if (includeInitializer) + headerCells.push(unist.makeTableCell([unist.makeText("Default value")])); + + headerCells.push(unist.makeTableCell([unist.makeText("Description")])); + var rows = [ - unist.makeTableRow([ - unist.makeTableCell([unist.makeText("Name")]), - unist.makeTableCell([unist.makeText("Type")]), - unist.makeTableCell([unist.makeText("Default value")]), - unist.makeTableCell([unist.makeText("Description")]) - ]) + unist.makeTableRow(headerCells) ]; - for (var i = 0; i < inputs.length; i++) { - var pName = inputs[i].name; - var pType = inputs[i].type; - var pDefault = inputs[i].init || ""; - var pDesc = inputs[i].docText || ""; + for (var i = 0; i < props.length; i++) { + var pName = props[i].name; + var pType = props[i].type; + var pDefault = props[i].initializer || ""; + var pDesc = props[i].docText || ""; if (pDesc) { - //pDesc = pDesc.trim().replace(/[\n\r]+/, " "); pDesc = pDesc.replace(/[\n\r]+/, " "); } @@ -226,11 +395,6 @@ function buildInputsTable(inputs: any[]) { var defaultCellContent; if (pDefault) { - /* - descCellContent.push(unist.makeHTML("
")); - descCellContent.push(unist.makeText(" Default value: ")); - descCellContent.push(unist.makeInlineCode(pDefault)); - */ defaultCellContent = unist.makeInlineCode(pDefault); } else { defaultCellContent = unist.makeText(""); @@ -238,53 +402,66 @@ function buildInputsTable(inputs: any[]) { var cells = [ unist.makeTableCell([unist.makeText(pName)]), - unist.makeTableCell([unist.makeInlineCode(pType)]), - //unist.makeTableCell([unist.makeInlineCode(pDefault)]), - unist.makeTableCell([defaultCellContent]), - unist.makeTableCell(descCellContent) + unist.makeTableCell([unist.makeInlineCode(pType)]) ]; + if (includeInitializer) + cells.push(unist.makeTableCell([defaultCellContent])); + + cells.push(unist.makeTableCell(descCellContent)); + rows.push(unist.makeTableRow(cells)); } - return unist.makeTable([null, null, null, null], rows); + let spacers = [null, null, null]; + + if (includeInitializer) + spacers.push(null); + + return unist.makeTable(spacers, rows); } -function buildOutputsTable(outputs: any[]) { - if (outputs.length === 0) { +function buildMethodsList(methods: MethodData[]) { + if (methods.length === 0) return null; - } - - var rows = [ - unist.makeTableRow([ - unist.makeTableCell([unist.makeText("Name")]), - unist.makeTableCell([unist.makeText("Type")]), - unist.makeTableCell([unist.makeText("Description")]) - ]) - ]; - for (var i = 0; i < outputs.length; i++){ - var eName = outputs[i].name; - var eType = outputs[i].type; - var eDesc = outputs[i].docText || ""; + let listItems = []; - if (eDesc) { - eDesc = eDesc.trim().replace(/[\n\r]+/, ' '); + for (let method of methods) { + let itemLines = []; + + itemLines.push(unist.makeInlineCode(method.getSignature())); + itemLines.push(unist.makeBreak()); + itemLines.push(unist.makeParagraph(remark().parse(method.docText).children)); + itemLines.push(unist.makeBreak()); + + let paramListItems = []; + + for (let param of method.params) { + let currParamSections = []; + + if (param.docText !== "") { + currParamSections.push(unist.makeInlineCode(param.name)); + + let optionalPart = param.optional ? "(Optional) " : ""; + + currParamSections.push(unist.makeText(" - " + optionalPart + param.docText)); + //currParamSections.push(unist.makeBreak()); + paramListItems.push(unist.makeListItem(unist.makeParagraph(currParamSections))); + } } - var cells = [ - unist.makeTableCell([unist.makeText(eName)]), - unist.makeTableCell([unist.makeInlineCode(eType)]), - unist.makeTableCell(remark().parse(eDesc).children) - ]; + itemLines.push(unist.makeListUnordered(paramListItems)); + - rows.push(unist.makeTableRow(cells)); + listItems.push(unist.makeListItem(unist.makeParagraph(itemLines))); } - return unist.makeTable([null, null, null], rows); + return unist.makeListUnordered(listItems); } + function isNodeExported(node: ts.Node): boolean { return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 || (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile); } \ No newline at end of file diff --git a/lib/config/DocProcessor/unistHelpers.js b/lib/config/DocProcessor/unistHelpers.js index 597ae764d4..cd669a7b5a 100644 --- a/lib/config/DocProcessor/unistHelpers.js +++ b/lib/config/DocProcessor/unistHelpers.js @@ -104,6 +104,12 @@ module.exports = { }; }, + makeBreak: function () { + return { + "type": "break" + } + }, + isHeading: function (node) { return node.type === "heading"; }, diff --git a/lib/content-services/content-node-selector/content-node-dialog.service.ts b/lib/content-services/content-node-selector/content-node-dialog.service.ts index dbbfee6f86..5bd13790fe 100644 --- a/lib/content-services/content-node-selector/content-node-dialog.service.ts +++ b/lib/content-services/content-node-selector/content-node-dialog.service.ts @@ -36,6 +36,8 @@ export class ContentNodeDialogService { private siteService: SitesService, private translation: TranslationService) { } + /** Opens a file browser at a chosen folder location. */ + /** @param folderNodeId ID of the folder to use */ openFileBrowseDialogByFolderId(folderNodeId: string): Observable { return Observable.fromPromise(this.documentListService.getFolderNode(folderNodeId)) .switchMap((node: MinimalNodeEntryEntity) => { @@ -43,18 +45,22 @@ export class ContentNodeDialogService { }); } + /** Opens a file browser at a chosen site location. */ openFileBrowseDialogBySite(): Observable { return this.siteService.getSites().switchMap((response: SitePaging) => { return this.openFileBrowseDialogByFolderId(response.list.entries[0].entry.guid); }); } + /** Opens a folder browser at a chosen site location. */ openFolderBrowseDialogBySite(): Observable { return this.siteService.getSites().switchMap((response: SitePaging) => { return this.openFolderBrowseDialogByFolderId(response.list.entries[0].entry.guid); }); } + /** Opens a folder browser at a chosen folder location. */ + /** @param folderNodeId ID of the folder to use */ openFolderBrowseDialogByFolderId(folderNodeId: string): Observable { return Observable.fromPromise(this.documentListService.getFolderNode(folderNodeId)) .switchMap((node: MinimalNodeEntryEntity) => { @@ -62,6 +68,10 @@ export class ContentNodeDialogService { }); } + /** Opens a dialog to copy or move an item to a new location. */ + /** @param action Name of the action (eg, "Copy" or "Move") to show in the title */ + /** @param contentEntry Item to be copied or moved */ + /** @param permission Permission for the operation */ openCopyMoveDialog(action: string, contentEntry: MinimalNodeEntryEntity, permission?: string): Observable { if (this.contentService.hasPermission(contentEntry, permission)) { @@ -91,10 +101,16 @@ export class ContentNodeDialogService { } } + /** Gets the translation of the dialog title. */ + /** @param action Name of the action to display in the dialog title */ + /** @param name Name of the item on which the action is being performed */ getTitleTranslation(action: string, name: string): string { return this.translation.instant(`NODE_SELECTOR.${action.toUpperCase()}_ITEM`, {name}); } + /** Opens a dialog to choose a folder to upload. */ + /** @param action Name of the action to show in the title */ + /** @param contentEntry Item to upload */ openUploadFolderDialog(action: string, contentEntry: MinimalNodeEntryEntity): Observable { const select = new Subject(); select.subscribe({ @@ -115,6 +131,9 @@ export class ContentNodeDialogService { return select; } + /** Opens a dialog to choose a file to upload. */ + /** @param action Name of the action to show in the title */ + /** @param contentEntry Item to upload */ openUploadFileDialog(action: string, contentEntry: MinimalNodeEntryEntity): Observable { const select = new Subject(); select.subscribe({ @@ -173,6 +192,7 @@ export class ContentNodeDialogService { return this.contentService.hasPermission(entry, 'create'); } + /** Closes the currently open dialog. */ close() { this.dialog.closeAll(); }