Socket
Socket
Sign inDemoInstall

doctor

Package Overview
Dependencies
13
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.28 to 0.1.29

133

lib/ast-node.js

@@ -5,19 +5,20 @@ var nast = require('./nice-ast');

/*
Creates an AST node from a plain object.
Creates an AST node from a plain object.
@class Represents an AST node.
@class Represents an AST node.
@param node Plain object to use as template for node.
@param [parent] Parent node of this node.
@param {Object} node
Plain object to use as template for node.
@param {AstNode} [parent]
Parent node of this node.
@property parent Parent of this node.
@property prev Previous sibling of this node.
@property next Next sibling of this node.
@example
var node = new AstNode({type: 'string', value: 'Hello, world!'});
@example
var node = new AstNode({type: 'string', value: 'Hello, world!'});
*/
function AstNode(node, parent) {
/* {AstNode} Parent of this node.*/
this.parent = parent || null;
/* {AstNode} Previous sibling of this node. */
this.prev = null;
/* {AstNode} Next sibling of this node. */
this.next = null;

@@ -41,15 +42,26 @@ this._items = {};

/* @param [value] Set value to this value. */
/*
@param key Item key.
@param value Item value.
*/
AstNode.prototype.item = function (key, value) {
/* @signature Gets an item value from a node.
@returns Value for this item.*/
/*
@signature Gets an item value from a node. If the node doesn't have the item
key, a recursive search will continue up through the parents.
@returns Value for this item.
*/
if (typeof value === 'undefined') {
return getNodeItem.call(this, key);
}
/* @signature Sets an item value for a particular node. */
/*
@signature Sets an item value for a particular node. Node items act like scoped
variables. Values set for a parent node can be seen by children nodes.
*/
this._items[key] = value;
};
/* Properly connect siblings to this node.
@param Index of this node. */
/*
Properly connect siblings to this node.
@param Index of this node.
*/
AstNode.prototype.fix = function (index) {

@@ -73,4 +85,6 @@ var nodes = this.parent.nodes;

/* Get the index of a node.
@returns {integer} */
/*
Get the index of a node.
@returns {integer}
*/
AstNode.prototype.index = function () {

@@ -90,5 +104,8 @@ if (!this.parent || !this.parent.nodes) {

/* Walk this node and its children, using the registered walk method. When a
node is appended, this is used to run all the rules for the appended node and
its children. */
/*
Walk this node and its children, using the registered walk method. When a
node is appended, this is used to run all the rules for the appended node and
its children.
@param {AstNode} node Node to walk.
*/
AstNode.prototype.walk = function (node) {

@@ -100,3 +117,6 @@ if (this._walk) {

/* Insert node after this one. */
/*
Insert node after this one.
@param {AstNode} node Node to insert.
*/
AstNode.prototype.after = function (node) {

@@ -112,3 +132,6 @@ node = nast.extendAst(node);

/* Insert node before this one. */
/*
Insert node before this one.
@param {AstNode} node Node to insert.
*/
AstNode.prototype.before = function (node) {

@@ -122,3 +145,6 @@ if (this.prev) {

/* Insert a new child node before any other child nodes. */
/*
Insert a new child node before any other child nodes.
@param {AstNode} node Node to prepend.
*/
AstNode.prototype.prepend = function (node) {

@@ -132,3 +158,6 @@ node = nast.extendAst(node);

/* Insert a new child node after any other child nodes. */
/*
Insert a new child node after any other child nodes.
@param {AstNode} node Node to append.
*/
AstNode.prototype.append = function (node) {

@@ -142,3 +171,5 @@ node = nast.extendAst(node);

/* Remove this node. */
/*
Remove this node.
*/
AstNode.prototype.remove = function () {

@@ -156,5 +187,7 @@ this._removed = true;

/* Return a lisp-like representation of this node. Useful while creating rules.
Gives you a terse look at the AST.
@returns {string} */
/*
Return a lisp-like representation of this node. Useful for debugging rules.
Gives you a terse look at the AST.
@returns {string}
*/
AstNode.prototype.lispify = function () {

@@ -164,4 +197,7 @@ return nast.lispify(this);

/* Returns true if this node has everything that node has.
@returns {boolean} */
/*
Returns true if this node has everything that node has.
@param {AstNode} node Node that has a subset of nodes/properties.
@returns {boolean}
*/
AstNode.prototype.like = function (node) {

@@ -171,4 +207,7 @@ return nast.like(this, node);

/* Return true if this node is idential to node.
@returns {boolean} */
/*
Return true if this node is idential to node.
@param {AstNode} node Node that has identical nodes/properties.
@returns {boolean}
*/
AstNode.prototype.equal = function (node) {

@@ -178,3 +217,6 @@ return nast.equal(this, node);

/* @return The PEG parser used in creating this AST. */
/*
Get the PEG parser used to create this AST.
@return PEG parser.
*/
AstNode.prototype.parser = function () {

@@ -190,5 +232,7 @@ var parser = null;

/* Compare this node to some arbitrary source. The source string will be
compiled to an AST, using the same grammar that was used to create this node.
*/
/*
Compare this node to some arbitrary source. The source string will be
compiled to an AST, using the same grammar that was used to create this node.
@param {string} source Source code to parse and compare to this node.
*/
AstNode.prototype.likeSource = function (source) {

@@ -207,3 +251,6 @@ var parser = this.parser();

/* Return an AST without the sibling and parent references. */
/*
Return an AST without the sibling and parent references.
@returns {Object} Plain object.
*/
AstNode.prototype.ast = function () {

@@ -213,2 +260,7 @@ return nast.cleanAst(this);

/*
Create an AST from source code.
@param {string} source Source code.
@returns {Object} AST.
*/
AstNode.prototype.fromSource = function (source) {

@@ -225,2 +277,7 @@ var parser = this.parser();

/*
Create an AST node from source code.
@param {string} source Source code.
@returns {Object} AST node.
*/
AstNode.prototype.nodeFromSource = function (source) {

@@ -227,0 +284,0 @@ var node = this.fromSource(source);

@@ -0,1 +1,5 @@

/*
Command-line interface into doctor.
*/
var opt = require('optimist');

@@ -6,3 +10,7 @@ var util = require('util');

/* Map command-line arguments to doctor's examine function. */
/*
Map command-line arguments to doctor's examine function.
@param {Object} argv Just the command-line arguments. In other words,
process.argv.slice(2).
*/
module.exports = function cli(argv) {

@@ -43,2 +51,5 @@ // optimist likes to use real args

.default('verbose', false)
.describe('verbose', 'print progress')
// .check(function (argv){

@@ -78,3 +89,7 @@ // return false

doctor.examine(options, function (err, result) {
doctor.examine(options, function (progress) {
if (argv.verbose) {
console.log(progress.message);
}
}, function (err, result) {
//throw new Error('x')

@@ -81,0 +96,0 @@ if (err) {

@@ -18,4 +18,2 @@ /*

var parser = require('./fork/parse-js');
var nast = require('./nice-ast');

@@ -33,2 +31,7 @@ var transform = require('./transform');

async.forEachSeries(options.files, function (file, cb) {
options.progressCb({
type: 'get-ast',
file: file,
message: 'get ast: ' + file
});
nast.astFromFile(options, file, function (e, ast) {

@@ -78,3 +81,3 @@ if (e) {

function pickupRequiredFiles(originalOptions, astList, astPathList, result, cb) {
var options = u.clone(originalOptions);
var options = _.clone(originalOptions);

@@ -180,2 +183,9 @@ if (!options.follow || !options.report) {

follow: false
}, function (progress) {
if (progress.type === 'get-ast') {
options.progressCb({
type: 'get-required-ast',
message: 'get required ast: ' + progress.file
});
}
}, function (err, report) {

@@ -266,4 +276,23 @@ if (err) {

@param options {Object}
@param cb {function} Function to call when doctor is finished.
@param {Object} options
Options for doctor.
@param {Array|String} options.files
One or more source files to inspect.
@param {String|boolean} options.output
Directory or filename for where to output the report file. If true, uses
default output directory name of "output".
@param {Array|String|boolean} options.view
One or more view directories to merge into output directory. If true, uses
default view.
@param {Array|String|boolean} options.report
One or more report modules. If true, uses default report module.
@param {Array|String|boolean} options.transform
One or more transform modules. If true, uses default transform module.
@param {Array|String|boolean} options.render
One or more render modules. If true, uses default render module.
@param {String|Object} options.grammar
Grammar file to use or a map of grammar files to use for each source
extension.
@param {function} [progressCb] Function to call with progress messages.
@param {function} cb Function to call when doctor is finished.

@@ -280,6 +309,6 @@ @example

*/
function examine(options, cb) {
function examine(options, progressCb, cb) {
(function (Path, fs, async, u) {
var syncFinished = false;
options = u.clone(options);
options = _.clone(options);
options.sync = options.sync || false;

@@ -289,2 +318,7 @@ if (typeof options.follow === 'undefined') {

}
if (typeof cb === 'undefined') {
cb = progressCb;
progressCb = function () {};
}
options.progressCb = progressCb;
var origCb = cb;

@@ -295,3 +329,3 @@ var syncError = null;

if (options.sync) {
path = u.sync.path;
Path = u.sync.path;
fs = u.sync.fs;

@@ -346,2 +380,6 @@ async = u.sync.async;

function finish(result) {
progressCb({
type: 'create-result',
message: 'create result'
});
if (!options.ast && !options.render) {

@@ -368,2 +406,6 @@ result = result.report;

}
progressCb({
type: 'write-output',
message: 'write output'
});
function writeFile(file, cb) {

@@ -381,3 +423,3 @@ var filePath = Path.join(outputDir, file);

// if circular references were introduced, this will fail
fileString = JSON.stringify(fileString);
fileString = JSON.stringify(fileString, null, 2);
} catch (e) {

@@ -399,2 +441,6 @@ return cb(e);

function renderReport(result) {
progressCb({
type: 'render-report',
message: 'render report'
});
result.files = {};

@@ -433,2 +479,6 @@ if (!result.report) {

function doMakeReport(ast) {
progressCb({
type: 'make-report',
message: 'make report'
});
makeReport(options, ast, function (err, report) {

@@ -445,2 +495,6 @@ if (err) {

function doTransformAst() {
progressCb({
type: 'transform-ast',
message: 'transform ast'
});
transformAst(options, astList, function (err, transformedAst) {

@@ -457,3 +511,3 @@ if (err) {

(function (originalOptions) {
var options = u.clone(originalOptions);
var options = _.clone(originalOptions);
options.files = moduleInfo.sorted || options.files;

@@ -488,2 +542,6 @@ getAst(options, astList, astPathList, function (err) {

}
progressCb({
type: 'follow-required',
message: 'find required modules'
});
findRequired(options, options.files, function (err, moduleInfo) {

@@ -498,2 +556,6 @@ if (err) {

function getCommentParser() {
progressCb({
type: 'get-comment-parser',
message: 'get comment parser'
});
nast.pegParser({grammar: 'comment-tags', sync: options.sync}, function (err, parser) {

@@ -515,2 +577,6 @@ if (err) {

function eachView(view, cb) {
progressCb({
type: 'copy-view',
message: 'copy view: ' + view
});
var viewChoices = [view, Path.join(__dirname, '../view', view)];

@@ -560,4 +626,7 @@ u.findDir(viewChoices,

/* __EXPERIMENTAL!__ __(and not even close to finished)__ Registers a compiler
for the .js extension that will compile harmony files to ECMAScript 5. */
/*
__EXPERIMENTAL!__ __(and not even close to finished)__ Registers a compiler
for the .js extension that will compile harmony files to ECMAScript 5.
@private
*/
function harmony() {

@@ -619,3 +688,3 @@

only to paths matching that regular expression.
@param enterCb {Function} Calls this function (passing it info) when a
@param enterCb {function} Calls this function (passing it info) when a
function is entered.

@@ -733,9 +802,7 @@ @param exitCb {Fucntion} Calls this function (passing it info) when a function

/* @private */
function callEnterHook() {
function _callEnterHook() {
hookEnterExit.enterCb.apply(null, arguments);
}
/* @private */
function callExitHook() {
function _callExitHook() {
hookEnterExit.exitCb.apply(null, arguments);

@@ -746,4 +813,3 @@ }

/* @private */
function callHook(type, filename, info) {
function _callHook(type, filename, info) {
info.hook = type;

@@ -757,7 +823,6 @@ if (filename) {

/* @private */
function wrapCall(fn, ctx, args, filename, info) {
callHook('enter', filename, info);
function _wrapCall(fn, ctx, args, filename, info) {
_callHook('enter', filename, info);
var result = fn.apply(ctx, args);
callHook('exit', filename, info);
_callHook('exit', filename, info);
return result;

@@ -771,6 +836,6 @@ }

registered to this filename.
@param enterCb {Function} Function to call when entering function. If exitCb
@param enterCb {function} Function to call when entering function. If exitCb
is not defined, enterCb will be called for exit as well.
@param [exitCb] {Function} Function to call when exiting function.
@param [sourceCb] {Function} Function to call when building the source for a function.
@param [exitCb] {function} Function to call when exiting function.
@param [sourceCb] {function} Function to call when building the source for a function.
@example

@@ -821,6 +886,6 @@ var doctor = require('doctor');

module.exports.hookEnterExit = hookEnterExit;
module.exports.callEnterHook = callEnterHook;
module.exports.callExitHook = callExitHook;
module.exports._callEnterHook = _callEnterHook;
module.exports._callExitHook = _callExitHook;
module.exports.insertEnterExitHooksSync = insertEnterExitHooksSync;
module.exports.callHook = callHook;
module.exports.wrapCall = wrapCall;
module.exports._callHook = _callHook;
module.exports._wrapCall = _wrapCall;

@@ -0,1 +1,2 @@

var fs = require('fs');

@@ -12,2 +13,10 @@ var peg = require('pegjs');

/*
Walks a tree of AST nodes.
@param {AstNode|Object} node AST node to walk.
@param {String} node.type Each AST node needs a type.
@param {Array} [node.nodes] Each AST node can optionally have a list of nodes to recurse.
@param {function} beforeCb Function to call before recursing into node.
@param {function} afterCb Function to call after recursing into node.
*/
function walk(node, beforeCb, afterCb) {

@@ -34,2 +43,11 @@ if (node._removed) {

/*
Walks a tree of AST nodes.
@param {AstNode|Object} node AST node to walk.
@param {String} node.type Each AST node needs a type.
@param {Array} [node.nodes] Each AST node can optionally have a list of nodes to
recurse.
@param {function} cb Function to call before and after recursing into node.
After recursing node, pseudo-node of type "end" will be passed to callback.
*/
function walkEnd(node, cb) {

@@ -48,2 +66,10 @@ walk(node,

/*
Takes a plain object representing a node, converts it to an AstNode and attaches
it to a parent in an AstNode tree.
@param {Object} node Plain object representing a node.
@param {String} node.type Type of the node.
@param {Array} [node.nodes] Child nodes that will also be converted.
@param {AstNode} parent Parent AstNode in the tree.
*/
function extendAst(node, parent) {

@@ -81,2 +107,6 @@ node = new AstNode(node);

/*
Converts a node (and its descendants) into plain objects that can be serialized.
@param {AstNode} node Node to convert.
*/
function cleanAst(node) {

@@ -108,31 +138,8 @@ var copy = {};

function parseCommentNode(node) {
var m;
var rawText = node.value;
if (node.multiline) {
rawText = ' ' + rawText;
}
var text = rawText.replace(/^(\s*\**\n)+/, '');
text = text.replace(/\n\s*\*+/g, '\n');
text = text.replace(/^\s*\*+/, '');
m = text.match(/^\s+/);
if (m) {
var lines = text.split('\n');
var buffer = [];
var tabRe = new RegExp('\\s{0,' + m[0].length + '}');
lines.forEach(function (line, i) {
m = line.match(tabRe);
if (m) {
line = line.substr(m[0].length);
line = line.replace(/\s*$/, '');
if (!line.match(/^\s*$/)) {
buffer.push(line);
}
}
});
text = buffer.join('\n');
}
node.text = text;
}
/*
Given doctor options and a file extension, retrieve an appropriate peg parser.
@param {Object} options Doctor options.
@param {String} extension File extension.
@param {function} cb Function to call with peg parser.
*/
function pegParser(options, extension, cb) {

@@ -245,2 +252,7 @@ (function (path, fs, async, u) {

/*
Add line numbers to ast nodes.
@param {Object|AstNode} ast Root AST node for file.
@param {String} source Source code for AST.
*/
function addLineNumbers(ast, source) {

@@ -283,2 +295,9 @@ var i;

/*
Convert source code to an AST.
@param {Object} options Doctor options.
@param {String} source Source code.
@param {String} extension File extension for source file.
@param {function} cb Function to call with AST.
*/
function astFromSource(options, source, extension, cb) {

@@ -315,2 +334,8 @@ if (typeof cb === 'undefined') {

/*
Convert file to AST.
@param {Object} options Doctor options.
@param {String} file File name.
@param {function} cb Function to call with AST.
*/
function astFromFile(options, file, cb) {

@@ -382,2 +407,7 @@ (function (fs) {

/*
Prepare rules from one or more rules files so they fire correctly.
@param {Array|String} rules One or more names of rules modules.
@param {String} defaultDir Default location for rules modules.
*/
function prepareRules(rules, defaultDir) {

@@ -421,2 +451,11 @@ rules = u.findRules(rules, defaultDir);

/*
Walk a tree of AST nodes and apply rules.
@param {Object} options Doctor options.
@param {Array|String} rules One or more rules file names.
@param {String} defaultDir Default location for rules modules.
@param {AstNode} ast Root of AST.
@param {function} nodeCb Function to call for each node.
@param {function} finalCb Function to call when finished walking.
*/
function walkWithRules(options, rules, defaultDir, ast, nodeCb, finalCb) {

@@ -476,2 +515,6 @@ var typeToRules;

/*
Convert a node to a lisp-like string, useful for debugging rules.
@param {AstNode|Object} node AST node to lispify.
*/
function lispify(node) {

@@ -492,2 +535,6 @@ if (!('value' in node) && !node.nodes) {

/*
Determine whether a node represents a primitive value.
@param {AstNode|Object} node AST node to test.
*/
function isValueNode(node) {

@@ -500,2 +547,9 @@ if (!('nodes' in node)) {

/*
Determine if a node is "like" another node, meaning it has all the properties of
that node.
@param {AstNode|Object} a Node to test for comparison. Must have all the
properties of node b.
@param {AstNode|Object} b Node that has a partial set of node a's properties.
*/
function like(a, b) {

@@ -508,3 +562,4 @@ if (a.type === 'var' && b.type === 'vars') {

// allow wildcards
if (b.type === 'name' && b.value === ('__' + a.type + '__')) {
if (b.type === 'name' &&
(b.value === ('__' + a.type + '__') || b.value === '__any__')) {
return true;

@@ -537,2 +592,7 @@ }

/*
Fills a diff object with line and column of unmatching nodes.
@param {AstNode} a Example node.
@param {AstNode} b Node that should have a's properties.
*/
function equalDiff(a, b, diff) {

@@ -550,2 +610,7 @@ diff.a = {

/*
Tests two AST nodes for equality.
@param {AstNode} a Example node.
@param {AstNode} b Node that should match a's properties.
*/
function equal(a, b, diff) {

@@ -575,2 +640,6 @@ diff = diff || {};

/*
Return the PEG parser for a given grammar file.
@param {String} grammarFile Name of grammar file.
*/
function parserForGrammar(grammarFile) {

@@ -577,0 +646,0 @@ if (grammarFile in pegParsers) {

@@ -6,3 +6,8 @@ var async = require('async');

/* Render the report with the render modules supplied in the options. */
/*
Render the report with the render modules supplied in the options.
@param {Object} options Doctor options.
@param {Object} report Report generated by doctor.
@param {function} cb Function to call when rendering is complete.
*/
function render(options, report, cb) {

@@ -9,0 +14,0 @@ (function (async, u) {

var nast = require('./nice-ast');
var u = require('./util');
var _ = require('underscore');
/*
Creates an empty report to be filled in by running rules against the AST.
@param {Object} options Doctor options.
@param {AstNode} ast Extended AST created from parsing source and extending with
AstNode.
*/
function Report(options, ast) {

@@ -8,4 +15,10 @@ this.options = options;

this.items = {root: {type: 'group', items: []}};
this._home = null;
}
/*
Walk AST, calling end callback with pseudo-node.
@param {AstNode} node Node of extended AST.
@param {function} cb Function to call at start and end of node.
*/
function walk(node, cb) {

@@ -22,3 +35,7 @@ nast.walk(node,

/* Run the report through the supplied report rules. */
/*
Run the report through the supplied report rules.
@param {function} cb Function to call when finished walking and applying rules
to the AST.
*/
Report.prototype.run = function (cb) {

@@ -53,2 +70,25 @@

function setHomePath(report, currentKey, allKeys) {
allKeys = allKeys || [];
if (allKeys.indexOf(currentKey) >= 0) {
return;
}
allKeys.push(currentKey);
if (!report.items.hasOwnProperty(currentKey)) {
return;
}
var item = report.items[currentKey];
item.isHomePath = true;
if (currentKey === 'root') {
return;
}
var groups = item.groups;
if (!groups) {
return;
}
_(groups).each(function (group) {
setHomePath(report, group, allKeys);
});
}
function finishRules(err) {

@@ -60,2 +100,6 @@ if (err) {

finalReport.items = self.items;
if (self._home) {
finalReport.home = self._home;
setHomePath(finalReport, finalReport.home);
}
cb(null, finalReport);

@@ -68,2 +112,7 @@ }

/*
Returns a report item.
@param {String} key Key of report item.
@returns {Object} Object representing a report item.
*/
Report.prototype.item = function (key) {

@@ -73,9 +122,15 @@ return this.items[key];

Report.prototype.ref = function (key) {
if (!(key in this.items)) {
throw new Error('trying to reference ' + key + ", but it doesn't exist");
}
return {$item: key};
};
// Can't remember why this is here. Leaving it in case something explodes.
//
// Report.prototype.ref = function (key) {
// if (!(key in this.items)) {
// throw new Error('trying to reference ' + key + ", but it doesn't exist");
// }
// return {$item: key};
// };
/*
Removes a report item.
@param {String} key Key of report item.
*/
Report.prototype.remove = function (key) {

@@ -87,13 +142,15 @@ var self = this;

var item = self.items[key];
// sometimes have to remove groups
if (item.type === 'group') {
console.log(item);
throw new Error('cannot delete group: ' + item.key);
if (item.type === 'group' && item.items && item.items.length > 0) {
throw new Error('cannot delete non-empty group: ' + item.key);
}
if (item.groups) {
item.groups.forEach(function (group, i) {
if (self.items[group]) {
var index = self.items[group].items.indexOf(key);
var groupItem = self.items[group];
if (groupItem) {
var index = groupItem.items.indexOf(key);
if (index >= 0) {
self.items[group].items.splice(index, 1);
groupItem.items.splice(index, 1);
if (groupItem.itemTypeCounts && groupItem.itemTypeCounts[item.type]) {
groupItem.itemTypeCounts[item.type]--;
}
}

@@ -106,2 +163,6 @@ }

/*
Adds a report item.
@param {String} item Report item.
*/
Report.prototype.add = function (item) {

@@ -122,23 +183,92 @@

if (self.items[item.key]) {
self.remove(item.key);
}
self.items[item.key] = item;
if (typeof item.groups === 'string') {
item.groups = [item.groups];
}
var newGroups = item.groups || [];
item.type = item.type || 'item';
item.name = item.name || item.key;
if (item.groups) {
if (typeof item.groups === 'string') {
item.groups = [item.groups];
if (newGroups.length === 0 && item.type === 'group') {
newGroups.push('root');
if (!item.groups) {
item.groups = [];
}
item.groups.forEach(function (group, i) {
if (!self.items[group]) {
self.add({key: group, type: 'group', items: []});
}
if (!self.items[group].items) {
self.items[group].items = [];
}
self.items[group].items.push(item.key);
});
} else if (item.type === 'group') {
self.items.root.items.push(item.key);
item.groups.push('root');
}
_(newGroups).each(function (group) {
var groupItem = self.items[group];
if (!groupItem) {
groupItem = {key: group, type: 'group', items: []};
self.add(groupItem);
}
if (!groupItem.items) {
groupItem.items = [];
}
if (!groupItem.itemTypeCounts) {
groupItem.itemTypeCounts = {};
}
if (!groupItem.itemTypeCounts[item.type]) {
groupItem.itemTypeCounts[item.type] = 0;
}
groupItem.items.push(item.key);
groupItem.itemTypeCounts[item.type]++;
});
// if (item.groups) {
// item.groups.forEach(function (group, i) {
// if (!self.items[group]) {
// self.add({key: group, type: 'group', items: []});
// }
// if (!self.items[group].items) {
// self.items[group].items = [];
// }
// self.items[group].items.push(item.key);
// });
// } else if (item.type === 'group') {
// self.items.root.items.push(item.key);
// }
if (item.isHome) {
self.home(item.key);
}
};
Report.prototype.home = function (item) {
/*
@signature Gets the key of the home item for the report.
@returns {String} Key of the home item.
*/
if (typeof item === 'undefined') {
return this._home;
}
/*
@signature Sets the key of the home item for the report.
@param {String} item Key of the home item.
*/
var key = item;
if (typeof item === 'object') {
key = item.key;
}
if (this._home) {
if (this.items.hasOwnProperty(this._home)) {
delete this.items[this._home].isHome;
}
this._home = null;
}
if (key && this.items.hasOwnProperty(key)) {
this.items[key].isHome = true;
this._home = key;
}
}
/*
Run an AST through a set of rules and return a report in a callback.
@param {Object} options Doctor options.
@param {AstNode} ast AST.
@param {function} cb Function to call when finished.
*/
function run(options, ast, cb) {

@@ -145,0 +275,0 @@ var report = new Report(options, ast);

var nast = require('./nice-ast');
var u = require('./util');
/* Transform the AST with the supplied transform rules. */
/*
Transform the AST with the supplied transform rules.
@param {Object} options Doctor options.
@param {AstNode} ast AST.
@param {function} cb Function to call when transformation is complete.
*/
function transform(options, ast, cb) {

@@ -6,0 +11,0 @@

@@ -0,1 +1,16 @@

/*
This module contains various utility functions used by doctor.
It notably contains some nasty synchronous versions of asynchronous modules.
Say what?
Yeah, that's right. This is so doctor can run synchronously or ansynhronously.
Doctor wants to run asynchronously, so when we have to run synchronously (such
as during that ugly startup phase where you have to deal with synchronous
require), we have to fake it out with synchronous versions of asynchronous
modules. This is ugly, but it's better than having to write two different
versions of doctor.
*/
var fs = require('fs');

@@ -46,2 +61,8 @@ var path = require('path');

var asyncSync = {
/*
Synchronous forEachSeries, with an asynchronous signature. Because it's
synchronous, it can also be used as the forEach function.
See the async module for details.
*/
forEachSeries: function (array, eachCb, finalCb) {

@@ -63,2 +84,7 @@ var error = null;

},
/*
Synchronous detect, with an asynchronous signature.
See the async module for details.
*/
detect: function (array, passCb, resultCb) {

@@ -82,2 +108,7 @@ var detected;

},
/*
Synchronous some, with an asynchronous signature.
See the async module for details.
*/
some: function (array, passCb, doneCb) {

@@ -101,2 +132,6 @@ var detected;

/*
Take an array or a value, and if it's a value, wrap it in an array.
@param maybeArray Array or value.
*/
function toArray(maybeArray) {

@@ -112,2 +147,6 @@ if (Array.isArray(maybeArray)) {

/*
Try to require module, or return null.
@param {String} moduleName Path to possible module.
*/
function requireMaybe(moduleName) {

@@ -123,3 +162,9 @@ try {

/* Compare the modified time stamps of two files. */
/*
Compare the modified time stamps of two files.
@param {String} a Path to first file.
@param {String} b Path to second file.
@param {function} cb Function to call with comparison value.
@param {boolean} sync Flag to force function to run synchronously.
*/
function compareFileDates(a, b, cb, sync) {

@@ -154,2 +199,5 @@ (function (fs) {

/*
@copy compareFileDates
*/
function compareFileDatesSync(a, b, cb) {

@@ -159,4 +207,8 @@ compareFileDates(a, b, cb, true);

/* Require the specified rule modules, either from the default location or from
the user-specified location. */
/*
Require the specified rule modules, either from the default location or from
the user-specified location.
@param {Array|string} optionRules Rule modules.
@param {string} defaultDir Default directory for rules.
*/
function findRules(optionRules, defaultDir) {

@@ -195,4 +247,8 @@ var allRules = [];

/* Require the specified function modules, either in the default location or
the user-specified location. */
/*
Require the specified function modules, either in the default location or
the user-specified location.
@param {Array|string} Possible modules to find.
@param {string} Default location to look for modules.
*/
function findFunctions(optionFunctions, defaultDir) {

@@ -227,11 +283,2 @@ var allFunctions = [];

/* Shallow-copy an object. */
function clone(obj) {
var newObj = {};
Object.keys(obj).forEach(function (key, i) {
newObj[key] = obj[key];
});
return newObj;
}
/* Check if a directory exists. */

@@ -262,5 +309,9 @@ function dirExists(dir, cb, sync) {

/* Find one of a list of files.
@param ifCb If one is found, do this.
@param elseCb If one is not found, do this. */
/*
Find one of a list of files.
@param {Array} fileList Possible files to find.
@param {function} ifCb If one is found, do this.
@param {function} elseCb If one is not found, do this.
@param {boolean} sync Flag to force function to run synchronously.
*/
function findFile(fileList, ifCb, elseCb, sync) {

@@ -282,2 +333,5 @@ (function (async, path) {

/*
@copy findFile
*/
function findFileSync(fileList, ifCb, elseCb) {

@@ -287,5 +341,9 @@ findFile(fileList, ifCb, elseCb, true);

/* Find one of a list of directories.
@param ifCb If one is found, do this.
@param elseCb If one is not found, do this. */
/*
Find one of a list of directories.
@param {Array} dirList Possible directories to find.
@param {function} ifCb If one is found, do this.
@param {function} elseCb If one is not found, do this.
@param {boolean} sync Flag to force function to run synchronously.
*/
function findDir(dirList, ifCb, elseCb, sync) {

@@ -308,2 +366,5 @@ (function (async, path, dirExists) {

/*
@copy findDir
*/
function findDirSync(dirList, ifCb, elseCb) {

@@ -313,3 +374,6 @@ findDir(dirList, ifCb, elseCb, true);

/* Compress fully-qualified paths down to minimal non-colliding lengths. */
/*
Compress absolute paths down to minimal non-colliding lengths.
@param {Array} pathList List of absolute paths.
*/
function localizePaths(pathList) {

@@ -358,6 +422,10 @@ // resolve paths so that './foo/bar.js' and 'foo/bar.js' resolve to the same localized path

/*
Create a copy of the object without the undefined properties.
@param obj Object to copy.
*/
function cleanUndefinedProperties(obj) {
var newObj;
var isArray = false;
if (typeof obj === 'object') {
if (typeof obj === 'object' && obj !== null) {
if (Array.isArray(obj)) {

@@ -381,2 +449,10 @@ newObj = [];

/*
Check if string starts with a captial letter.
@param {string} string String to check.
*/
function isCapitalized(string) {
return (string && string.match(/^[A-Z]/)) ? true : false;
}
module.exports.findRules = findRules;

@@ -387,6 +463,6 @@ module.exports.findFunctions = findFunctions;

module.exports.compareFileDates = compareFileDates;
module.exports.clone = clone;
module.exports.toArray = toArray;
module.exports.localizePaths = localizePaths;
module.exports.cleanUndefinedProperties = cleanUndefinedProperties;
module.exports.isCapitalized = isCapitalized;

@@ -393,0 +469,0 @@ module.exports.fs = fs;

@@ -5,3 +5,3 @@ {

"description": "Create documentation from a JavaScript AST.",
"version": "0.1.28",
"version": "0.1.29",
"homepage": "https://github.com/jdeal/doctor",

@@ -22,7 +22,6 @@ "repository": {

"handlebars": "~1.0.0",
"github-flavored-markdown": "~1.0.0",
"underscore": "~1.2.2",
"mkdirp": "~0.2.1",
"showdown": "~0.0.1",
"js-yaml": "~0.3.5"
"js-yaml": "~0.3.5",
"marked": "~0.2.5"
},

@@ -29,0 +28,0 @@ "devDependencies": {

'use strict';
var ghm = require('github-flavored-markdown');
var Showdown = require('showdown').Showdown;
var marked = require('marked');
var _ = require('underscore');
var converter = new Showdown.converter();
marked.setOptions({
gfm: true
});

@@ -14,2 +15,9 @@ function stripParagraphTag(text) {

function stripTrailingNewline(text) {
if (text.charAt(text.length - 1) === '\n') {
text = text.substring(0, text.length - 1);
}
return text;
}
function markdownToHtml(nodes) {

@@ -19,6 +27,8 @@ if (nodes instanceof Object) {

//nodes.description = stripParagraphTag(converter.makeHtml(nodes.description));
nodes.description = converter.makeHtml(nodes.description);
//nodes.description = converter.makeHtml(nodes.description);
nodes.description = stripTrailingNewline(marked(nodes.description));
}
if (nodes.content) {
nodes.content = ghm.parse(nodes.content);
//nodes.content = ghm.parse(nodes.content);
nodes.content = stripTrailingNewline(marked(nodes.content));
}

@@ -25,0 +35,0 @@ _(nodes).each(function (value) {

var Path = require('path');
var _ = require('underscore');
function isCapitalized(string) {
return (string && string.match(/^[A-Z]/)) ? true : false;
}
var util = require('../lib/util');

@@ -101,5 +99,25 @@ // make a set of params to match the signature

var items = [];
var properties;
if (node.properties) {
properties = node.properties.slice(0);
}
if (node.item('classProperties')) {
if (!properties) {
properties = [];
}
properties = properties.concat(node.item('classProperties'));
}
if (properties) {
properties = properties.map(function (prop) {
if (prop.name.length > 1 && prop.name[0] === '_') {
prop.isPrivate = true;
}
return prop;
});
}
var fnItem = {
type: 'function',
constructorFunction: isCapitalized(name),
// deprecated
//constructorFunction: isCapitalized(name),
isConstructor: util.isCapitalized(name),
key: node.item('module') + '.' + name,

@@ -111,3 +129,3 @@ params: fnNode.params,

description: node.description,
properties: node.properties,
properties: properties,
examples: node.examples,

@@ -122,3 +140,3 @@ visibility: node.visibility,

functionSignatures(fnNode, body.nodes[0], fnItem, signatures);
if (fnItem.constructorFunction) {
if (fnItem.isConstructor) {
var classItem = {

@@ -295,3 +313,3 @@ type: 'class',

if (item && item.type === 'function') {
if (isCapitalized(name)) {
if (util.isCapitalized(name)) {
item.isConstructor = true;

@@ -354,4 +372,5 @@ node.item('moduleScopeNode').item('var.class:' + name, item);

var item = {};
if (valueNode.visibility !== 'private') {
item.api = true;
if (valueNode.visibility === 'private' || (exportName.length > 1 &&
exportName[0] === '_')) {
item.isPrivate = true;
}

@@ -361,3 +380,3 @@ if (exportName === 'anonymous') {

if (exports.isConstructor) {
item.constructorFunction = exports.isConstructor;
item.isConstructor = exports.isConstructor;
}

@@ -517,2 +536,4 @@ if (exports.name) {

node.item('scopeNode', node);
node.item('functionCommentNode', node);
node.item('isConstructor', util.isCapitalized(name));
}

@@ -535,2 +556,4 @@ });

saveVar(node, name, fnNode);
node.item('functionCommentNode', node);
node.item('isConstructor', util.isCapitalized(name));
}

@@ -547,2 +570,22 @@ });

/* pick up properties inside constructor */
rules.push({
type: 'assign',
match: function (node) {
return node.item('isConstructor') &&
node.likeSource('this.__name__ = __any__');
},
report: function (node, report) {
var commentNode = node.item('functionCommentNode');
if (!commentNode.item('classProperties')) {
commentNode.item('classProperties', []);
}
commentNode.item('classProperties').push({
name: node.nodes[1].nodes[1].value,
description: node.description,
types: node.types
});
}
});
/*

@@ -878,3 +921,3 @@ var f = x;

items = items.concat(functionReportItems(method.node, method.value, methodName, {
method: true,
isMethod: true,
key: node.item('module') + '.class.' + className + '.' + methodName,

@@ -928,6 +971,42 @@ groups: [groupName]

});
if (report.items.modules) {
var moduleNames = [];
report.items.modules.items.forEach(function (itemKey, i) {
var item = report.items[itemKey];
moduleNames.push(item.name);
});
moduleNames = util.localizePaths(moduleNames);
report.items.modules.items.forEach(function (itemKey, i) {
var item = report.items[itemKey];
item.name = moduleNames[i];
});
}
var sortOrder = ['readme', 'modules', 'classes'];
report.item('root').items = _(report.item('root').items).sortBy(function (item) {
return sortOrder.indexOf(item);
});
report.item('root').isSorted = true;
}
});
/*
Remove classes or modules group if not needed.
*/
rules.push({
type: 'end-files',
report: function (node, report) {
var modulesGroup = report.item('modules');
var classesGroup = report.item('classes');
if (!modulesGroup.items || modulesGroup.items.length === 0) {
report.remove('modules');
}
if (!classesGroup.items || classesGroup.items.length === 0) {
report.remove('classes');
}
}
});
rules.push({
type: 'markdown',

@@ -942,3 +1021,3 @@ report: function (node, report) {

}
return {
var item = {
key: 'readme.' + node.path,

@@ -950,2 +1029,6 @@ name: node.path,

};
if (node.path === 'README.md') {
item.isHome = true;
}
return item;
}

@@ -952,0 +1035,0 @@ });

@@ -18,11 +18,11 @@ /*global suite:false, test:false*/

test('clone', function () {
var obj = { a: "a", b: "b" };
var result = util.clone(obj);
// test('clone', function () {
// var obj = { a: "a", b: "b" };
// var result = util.clone(obj);
assert.deepEqual(obj, result);
obj.a = "not a";
assert.equal(obj.a, "not a");
assert.equal(result.a, "a");
});
// assert.deepEqual(obj, result);
// obj.a = "not a";
// assert.equal(obj.a, "not a");
// assert.equal(result.a, "a");
// });

@@ -29,0 +29,0 @@ test('findFile exists', function (done) {

@@ -7,2 +7,3 @@ var rules = [];

node.item('path', node.path);
node.item('functions', {});
}

@@ -77,2 +78,5 @@ });

},
"types": function (value, node) {
node.types = value;
},
"param": function (value, node) {

@@ -82,3 +86,21 @@ if (!node.paramTags) {

}
node.paramTags[value.name] = value;
var paramTag = {};
if (!node.paramTags[value.name]) {
node.paramTags[value.name] = paramTag;
} else {
paramTag = node.paramTags[value.name];
}
paramTag.name = value.name;
if (value.property) {
if (!paramTag.properties) {
paramTag.properties = [];
}
value.name = value.property;
delete value.property;
paramTag.properties.push(value);
} else {
Object.keys(value).forEach(function (key) {
paramTag[key] = value[key];
});
}
},

@@ -117,2 +139,5 @@ "returns": function (value, node) {

node.checksSignature = true;
},
"copy": function (value, node) {
node.copyTags = value;
}

@@ -160,2 +185,5 @@ };

node.name = nameNode.value;
if (node.name) {
node.item('functions')[node.name] = node;
}
node.params = [];

@@ -165,9 +193,22 @@ node.paramIndex = {};

var paramTags = node.paramTags;
// for anonymous functions assigned to variables, paramTags are in parent --
// for functions assigned to variables, paramTags are in parent --
// i.e. '/* @param a */ var parent = function (a) {}'
if (node.paramTags === undefined && node.name === undefined &&
node.parent && node.parent.type === 'assign') {
if (node.paramTags === undefined && node.parent &&
node.parent.type === 'assign' && node.parent.paramTags) {
paramTags = node.parent.paramTags;
}
node.item('paramTags', paramTags);
if (node.copyTags) {
var tagSource = node.item('functions')[node.copyTags];
if (tagSource) {
if (!node.description && tagSource.description) {
node.description = tagSource.description;
}
if (!paramTags && tagSource.item('paramTags')) {
paramTags = tagSource.item('paramTags');
}
}
}
paramsNodes.forEach(function (paramNode, i) {

@@ -181,2 +222,5 @@ var param = {

var tagValue = paramTags[param.name];
// if (node.item('path') === 'cli') {
// console.log(tagValue)
// }
Object.keys(tagValue).forEach(function (key, i) {

@@ -191,2 +235,5 @@ if (key !== 'name') {

});
// if (node.item('path') === 'cli') {
// console.log(node.params)
// }
}

@@ -193,0 +240,0 @@

@@ -35,3 +35,3 @@ var _ = require('underscore');

function makeHook(options, type, node) {
var hookNode = node.fromSource('__doctor.callHook(' +
var hookNode = node.fromSource('__doctor._callHook(' +
JSON.stringify(type) + ',' +

@@ -114,3 +114,3 @@ JSON.stringify(hookFilename(options)) + ',' +

var args = node.nodes[1];
var wrap = node.nodeFromSource('__doctor.wrapCall(' +
var wrap = node.nodeFromSource('__doctor._wrapCall(' +
JSON.stringify(hookFilename(transform.options)) + ', ' +

@@ -117,0 +117,0 @@ hookInfoString(transform.options, node) + ')');

'use strict';
/*global alert: false, $: false */
/*global alert: false, $: false, SyntaxHighlighter: false */
SyntaxHighlighter.defaults['gutter'] = false;
SyntaxHighlighter.defaults.gutter = false;
function capitalize(string) {
var doc = {}; // namespace
doc.capitalize = function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
};
var doc = {}; // namespace
doc.idify = function idify(key) {
return key.replace(/\//g, '__').replace(/\./g, '--');
};

@@ -16,3 +20,3 @@ doc.addChild = function (parent, childName, text, cssClass) {

if (text) {
child.text(text);
child.html(text);
}

@@ -90,5 +94,5 @@ if (cssClass) {

doc.getDisplayType = function (item) {
if (item.method) {
if (item.isMethod) {
return "method";
} else if (item.constructorFunction) {
} else if (item.isConstructor) {
return "constructor";

@@ -102,3 +106,11 @@ } else {

if (types && types.length > 0) {
return '<span class="types">{' + types.join(', ') + '}</span> ';
var html = '<span class="types">{';
types.forEach(function (type, i) {
if (i > 0) {
html += ', ';
}
html += '<span class="class-link" data-class-name="' + type + '">' + type + '</span>';
});
html += '}</span>';
return html;
}

@@ -109,4 +121,5 @@ return '';

doc.paramHtml = function (param) {
var html = '<dl class="param"><dt>' + doc.typesHtml(param.types) +
'<span class="paramName">' + param.name + '</span>';
var html = '<dl class="param"><dt>' +
'<span class="paramName">' + param.name + '</span> ' +
doc.typesHtml(param.types);

@@ -120,2 +133,10 @@ // if (param.optional) {

var description = '<div>' + (param.description || '') + '</div>';
if (param.properties) {
description += '<dl>';
param.properties.forEach(function (property) {
description += '<dt><span class="paramName">' + property.name + '</span> ' +
doc.typesHtml(property.types) + '</dt><dd>' + property.description + '</dd>';
});
description += '</dl>';
}
html += '</dt><dd>' + description + '</dd>';

@@ -176,6 +197,11 @@ return html;

if (item.properties && item.properties.length > 0) {
var html = '<h3>Properties:</h3>';
item.properties.forEach(function (type) {
html += doc.paramHtml(type);
var html = '';
item.properties.forEach(function (prop) {
if (doc.isVisible(prop)) {
html += doc.paramHtml(prop);
}
});
if (html !== '') {
html = '<h3>Properties:</h3>' + html;
}
parent.append(html);

@@ -221,3 +247,8 @@ }

if (i > 0) {
paramsString += ', ';
paramsString += ',';
if (param.optional) {
paramsString += '&nbsp;';
} else {
paramsString += ' ';
}
}

@@ -230,3 +261,3 @@ paramsString += param.name;

if (params.length > 0) {
paramsString = ' ' + paramsString + ' ';
paramsString = ' ' + paramsString + '&nbsp;';
}

@@ -273,3 +304,3 @@ //var nameDiv = doc.addDiv(parent, '', 'itemName');

doc.isPublicMethod = function (item) {
return item.method && (!item.visibility || item.visibility === 'public');
return item.isMethod && (!item.visibility || item.visibility === 'public');
// || doc.isVisible(doc.getParentItem(report, item));

@@ -279,3 +310,3 @@ };

doc.isVisible = function (item) {
return item.api || doc.isPublicMethod(item);
return !item.isPrivate || doc.isPublicMethod(item);
// || item.visibility === 'public';

@@ -300,3 +331,3 @@ };

doc.showClass = function (report, item) {
if (item.constructorFunction) {
if (item.isConstructor) {
return doc.isVisible(item) || doc.hasVisibleChildren(report, item);

@@ -325,8 +356,25 @@ }

var content = $('#content');
content.html('');
if (!nested) {
// if (item.items) {
// item.items.forEach(function (key) {
// var item = report.items[key];
// var title = doc.addChild(content, 'h2', doc.itemDisplayName(item), 'contentTitle');
// title.wrapInner('<a></a>');
// title.click(function () {
// $('#' + doc.idify(item.key)).click();
// });
// doc.addChild(content, 'p', item.type, 'contentType');
// });
// }
return;
}
content.html('');
//doc.addDiv(content, doc.itemDisplayName(item), 'contentTitle');
doc.addChild(content, 'h1', doc.itemDisplayName(item), 'contentTitle');
if (item.type === 'readme') {

@@ -345,2 +393,15 @@ var brushes = ['bash', 'shell', 'cpp', 'c', 'css', 'diff', 'patch',

});
$('pre > code').each(function (i, code) {
code = $(code);
var brush;
if (code.attr('class')) {
brush = code.attr('class');
brush = brush.substring(brush.indexOf('lang-') + 'lang-'.length);
}
if (brushes.indexOf(brush) < 0) {
brush = 'plain';
}
code.parent().addClass('brush:' + brush);
code.contents().unwrap();
});
SyntaxHighlighter.highlight();

@@ -350,4 +411,3 @@ return;

//doc.addDiv(content, doc.itemDisplayName(item), 'contentTitle');
doc.addChild(content, 'h1', doc.itemDisplayName(item), 'contentTitle');
doc.addChild(content, 'p', item.type, 'contentType');

@@ -375,3 +435,3 @@ if (item.module) {

if (item.constructorFunction || item.type === 'module-function') {
if (item.isConstructor || item.type === 'module-function') {
itemKeys = [item.key].concat(itemKeys);

@@ -390,13 +450,15 @@ }

items.sort(function (a, b) {
var nameA = doc.itemDisplayName(a);
var nameB = doc.itemDisplayName(b);
if (nameA < nameB) {
return -1;
} else if (nameA > nameB) {
return 1;
} else {
return 0;
}
});
if (item.key !== 'root') {
items.sort(function (a, b) {
var nameA = doc.itemDisplayName(a);
var nameB = doc.itemDisplayName(b);
if (nameA < nameB) {
return -1;
} else if (nameA > nameB) {
return 1;
} else {
return 0;
}
});
}

@@ -457,8 +519,39 @@ var parentItem = item;

doc.renderToc = function (report, group, element, nested) {
doc.hasTocItems = function (item) {
if (item.itemTypeCounts) {
for (var itemType in item.itemTypeCounts) {
if (item.itemTypeCounts[itemType]) {
if (itemType in doc.tocTypeSet) {
return true;
}
}
}
}
};
doc.classNavMap = {};
doc.classNav = function (className) {
if (className in doc.classNavMap) {
return doc.classNavMap[className];
}
var nav = $('.nav-' + className);
if (nav.length === 1) {
doc.classNavMap[className] = nav;
} else {
doc.classNavMap[className] = null;
}
return doc.classNavMap[className];
};
doc.renderToc = function (report, group, element, nested, hide) {
var ul = $('<ul>');
element.append(ul);
var clickedHome = false;
if (group.items) {
group.items.sort();
if (!group.isSorted) {
group.items.sort();
}

@@ -471,3 +564,22 @@ group.items.forEach(function (itemKey, i) {

var a = $('<a href="#">' + doc.itemDisplayName(item) + '</a>');
var expander = '&nbsp;';
if (item.items && item.items.length > 0) {
expander = '&#9656;&nbsp;';
}
var chevronStyle = "";
if (!doc.hasTocItems(item)) {
chevronStyle = "display:none";
}
var a = $('<a id="' + doc.idify(itemKey) + '" class="nav-' +
doc.itemDisplayName(item) +
' expanded" + " href="#"><span class="chevron" style="' +
chevronStyle + '">&nbsp;<span id="expand_' + itemKey +
'">&#9656;</span><span id="contract_' + itemKey +
'" style="display:none">&#9662;</span></span>&nbsp;' +
doc.itemDisplayName(item) + '</a>');
if (hide) {
a.nextAll();
}
li.append(a);

@@ -485,13 +597,52 @@

if (item.items) {
if (a.data('rendered')) {
a.nextAll().toggle();
if (a.data('expanded')) {
a.nextAll().hide();
a.data('expanded', false);
$('#contract_' + itemKey).hide();
$('#expand_' + itemKey).show();
} else {
doc.renderToc(report, item, li, true);
a.data('rendered', true);
//if (a.data('rendered')) {
a.nextAll().show();
//} else {
// console.log("*");
// doc.renderToc(report, item, li, true);
//}
a.data('expanded', true);
$('#expand_' + itemKey).hide();
$('#contract_' + itemKey).show();
}
}
doc.renderContent(report, item, nested);
SyntaxHighlighter.highlight();
$('.class-link').each(function (i, linkNode) {
var link = $(linkNode);
var className = link.data('class-name');
var classNav = doc.classNav(className);
if (classNav) {
link.wrap('<a href="#"></a>');
link.click(function () {
if (!$('#classes').data('expanded')) {
$('#classes').click();
}
setTimeout(function () {
$('.nav-' + link.data('class-name')).click();
});
});
}
});
});
if (!a.data('rendered')) {
doc.renderToc(report, item, li, true, true);
a.nextAll().hide();
a.data('rendered', true);
}
if (item.isHomePath && !item.clickedHomePath) {
item.clickedHomePath = true;
setTimeout(function () {
a.click();
}, 0);
}
}

@@ -498,0 +649,0 @@ });

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc