123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // treeify.js
- // Luke Plaster <notatestuser@gmail.com>
- // https://github.com/notatestuser/treeify.js
- // do the universal module definition dance
- (function (root, factory) {
- if (typeof exports === 'object') {
- module.exports = factory();
- } else if (typeof define === 'function' && define.amd) {
- define(factory);
- } else {
- root.treeify = factory();
- }
- }(this, function() {
- function makePrefix(key, last) {
- var str = (last ? '└' : '├');
- if (key) {
- str += '─ ';
- } else {
- str += '──┐';
- }
- return str;
- }
- function filterKeys(obj, hideFunctions) {
- var keys = [];
- for (var branch in obj) {
- // always exclude anything in the object's prototype
- if (!obj.hasOwnProperty(branch)) {
- continue;
- }
- // ... and hide any keys mapped to functions if we've been told to
- if (hideFunctions && ((typeof obj[branch])==="function")) {
- continue;
- }
- keys.push(branch);
- }
- return keys;
- }
- function growBranch(key, root, last, lastStates, showValues, hideFunctions, callback) {
- var line = '', index = 0, lastKey, circular, lastStatesCopy = lastStates.slice(0);
- if (lastStatesCopy.push([ root, last ]) && lastStates.length > 0) {
- // based on the "was last element" states of whatever we're nested within,
- // we need to append either blankness or a branch to our line
- lastStates.forEach(function(lastState, idx) {
- if (idx > 0) {
- line += (lastState[1] ? ' ' : '│') + ' ';
- }
- if ( ! circular && lastState[0] === root) {
- circular = true;
- }
- });
- // the prefix varies based on whether the key contains something to show and
- // whether we're dealing with the last element in this collection
- line += makePrefix(key, last) + key;
- // append values and the circular reference indicator
- showValues && (typeof root !== 'object' || root instanceof Date) && (line += ': ' + root);
- circular && (line += ' (circular ref.)');
- callback(line);
- }
- // can we descend into the next item?
- if ( ! circular && typeof root === 'object') {
- var keys = filterKeys(root, hideFunctions);
- keys.forEach(function(branch){
- // the last key is always printed with a different prefix, so we'll need to know if we have it
- lastKey = ++index === keys.length;
- // hold your breath for recursive action
- growBranch(branch, root[branch], lastKey, lastStatesCopy, showValues, hideFunctions, callback);
- });
- }
- };
- // --------------------
- var Treeify = {};
- // Treeify.asLines
- // --------------------
- // Outputs the tree line-by-line, calling the lineCallback when each one is available.
- Treeify.asLines = function(obj, showValues, hideFunctions, lineCallback) {
- /* hideFunctions and lineCallback are curried, which means we don't break apps using the older form */
- var hideFunctionsArg = typeof hideFunctions !== 'function' ? hideFunctions : false;
- growBranch('.', obj, false, [], showValues, hideFunctionsArg, lineCallback || hideFunctions);
- };
- // Treeify.asTree
- // --------------------
- // Outputs the entire tree, returning it as a string with line breaks.
- Treeify.asTree = function(obj, showValues, hideFunctions) {
- var tree = '';
- growBranch('.', obj, false, [], showValues, hideFunctions, function(line) {
- tree += line + '\n';
- });
- return tree;
- };
- // --------------------
- return Treeify;
- }));
|