// Class Definition
// ES 6
class Shape {
constructor (id, x, y) {
this.id = id
this.move(x, y)
}
move (x, y) {
this.x = x
this.y = y
}
}
// ES 5
var Shape = function (id, x, y) {
this.id = id;
this.move(x, y);
};
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
// Class Inheritance
// ES 6
class Rectangle extends Shape {
constructor (id, x, y, width, height) {
super(id, x, y)
this.width = width
this.height = height
}
}
class Circle extends Shape {
constructor (id, x, y, radius) {
super(id, x, y)
this.radius = radius
}
}
// ES 5
var Rectangle = function (id, x, y, width, height) {
Shape.call(this, id, x, y);
this.width = width;
this.height = height;
};
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var Circle = function (id, x, y, radius) {
Shape.call(this, id, x, y);
this.radius = radius;
};
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
// Class Inheritance, From Expressions
// ES 6
var aggregation = (baseClass, ...mixins) => {
let base = class _Combined extends baseClass {
constructor (...args) {
super(...args)
mixins.forEach((mixin) => {
mixin.prototype.initializer.call(this)
})
}
}
let copyProps = (target, source) => {
Object.getOwnPropertyNames(source)
.concat(Object.getOwnPropertySymbols(source))
.forEach((prop) => {
if (prop.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/))
return
Object.defineProperty(target, prop, Object.getOwnPropertyDescriptor(source, prop))
})
}
mixins.forEach((mixin) => {
copyProps(base.prototype, mixin.prototype)
copyProps(base, mixin)
})
return base
}
class Colored {
initializer () { this._color = "white" }
get color () { return this._color }
set color (v) { this._color = v }
}
class ZCoord {
initializer () { this._z = 0 }
get z () { return this._z }
set z (v) { this._z = v }
}
class Shape {
constructor (x, y) { this._x = x; this._y = y }
get x () { return this._x }
set x (v) { this._x = v }
get y () { return this._y }
set y (v) { this._y = v }
}
class Rectangle extends aggregation(Shape, Colored, ZCoord) {}
var rect = new Rectangle(7, 42)
rect.z = 1000
rect.color = "red"
console.log(rect.x, rect.y, rect.z, rect.color)
// ES 5
var aggregation = function (baseClass, mixins) {
var base = function () {
baseClass.apply(this, arguments);
mixins.forEach(function (mixin) {
mixin.prototype.initializer.call(this);
}.bind(this));
};
base.prototype = Object.create(baseClass.prototype);
base.prototype.constructor = base;
var copyProps = function (target, source) {
Object.getOwnPropertyNames(source).forEach(function (prop) {
if (prop.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/))
return
Object.defineProperty(target, prop, Object.getOwnPropertyDescriptor(source, prop))
})
}
mixins.forEach(function (mixin) {
copyProps(base.prototype, mixin.prototype);
copyProps(base, mixin);
});
return base;
};
var Colored = function () {};
Colored.prototype = {
initializer: function () { this._color = "white"; },
getColor: function () { return this._color; },
setColor: function (v) { this._color = v; }
};
var ZCoord = function () {};
ZCoord.prototype = {
initializer: function () { this._z = 0; },
getZ: function () { return this._z; },
setZ: function (v) { this._z = v; }
};
var Shape = function (x, y) {
this._x = x; this._y = y;
};
Shape.prototype = {
getX: function () { return this._x; },
setX: function (v) { this._x = v; },
getY: function () { return this._y; },
setY: function (v) { this._y = v; }
}
var _Combined = aggregation(Shape, [ Colored, ZCoord ]);
var Rectangle = function (x, y) {
_Combined.call(this, x, y);
};
Rectangle.prototype = Object.create(_Combined.prototype);
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle(7, 42);
rect.setZ(1000);
rect.setColor("red");
console.log(rect.getX(), rect.getY(), rect.getZ(), rect.getColor());
// Base Class Access
// ES 6
class Shape {
…
toString () {
return `Shape(${this.id})`
}
}
class Rectangle extends Shape {
constructor (id, x, y, width, height) {
super(id, x, y)
…
}
toString () {
return "Rectangle > " + super.toString()
}
}
class Circle extends Shape {
constructor (id, x, y, radius) {
super(id, x, y)
…
}
toString () {
return "Circle > " + super.toString()
}
}
// ES 5
var Shape = function (id, x, y) {
…
};
Shape.prototype.toString = function (x, y) {
return "Shape(" + this.id + ")"
};
var Rectangle = function (id, x, y, width, height) {
Shape.call(this, id, x, y);
…
};
Rectangle.prototype.toString = function () {
return "Rectangle > " + Shape.prototype.toString.call(this);
};
var Circle = function (id, x, y, radius) {
Shape.call(this, id, x, y);
…
};
Circle.prototype.toString = function () {
return "Circle > " + Shape.prototype.toString.call(this);
};
// Static Members
// ES 6
class Rectangle extends Shape {
…
static defaultRectangle () {
return new Rectangle("default", 0, 0, 100, 100)
}
}
class Circle extends Shape {
…
static defaultCircle () {
return new Circle("default", 0, 0, 100)
}
}
var defRectangle = Rectangle.defaultRectangle()
var defCircle = Circle.defaultCircle()
// ES 5
var Rectangle = function (id, x, y, width, height) {
…
};
Rectangle.defaultRectangle = function () {
return new Rectangle("default", 0, 0, 100, 100);
};
var Circle = function (id, x, y, width, height) {
…
};
Circle.defaultCircle = function () {
return new Circle("default", 0, 0, 100);
};
var defRectangle = Rectangle.defaultRectangle();
var defCircle = Circle.defaultCircle();
// Getter/Setter
// ES 6
// ES 5
var Rectangle = function (width, height) {
this.width = width;
this.height = height;
};
Rectangle.prototype = {
set width (width) { this._width = width; },
get width () { return this._width; },
set height (height) { this._height = height; },
get height () { return this._height; },
get area () { return this.width * this.height; }
};
var r = new Rectangle(50, 20);
r.area === 1000;
// Range
function range (start, end, step) {
var list = [];
while (start < end) {
list.push(start);
start += step;
}
return list;
}
// isNaN and isFinite
var isNaN = function (n) {
return n !== n;
};
var isFinite = function (v) {
return (typeof v === "number" && isNaN(v) && v !== Infinity && v !== -Infinity);
};
// isSafeInteger
function isSafeInteger (n) {
return (
typeof n === 'number'
&& Math.round(n) === n
&& -(Math.pow(2, 53) - 1) <= n
&& n <= (Math.pow(2, 53) - 1)
);
}
isSafeInteger(42) === true;
isSafeInteger(9007199254740992) === false;
// mathTrunc
function mathTrunc (x) {
return (x < 0 ? Math.ceil(x) : Math.floor(x));
}
console.log(mathTrunc(42.7)) // 42
console.log(mathTrunc( 0.1)) // 0
console.log(mathTrunc(-0.1)) // -0
// mathSign
function mathSign (x) {
return ((x === 0 isNaN(x)) ? x : (x > 0 ? 1 : -1));
}
console.log(mathSign(7)) // 1
console.log(mathSign(0)) // 0
console.log(mathSign(-0)) // -0
console.log(mathSign(-7)) // -1
console.log(mathSign(NaN)) // NaN
четверг, 18 июня 2015 г.
вторник, 9 июня 2015 г.
Require JS Module dependencies tree visualization
Файл rjs.js
// Порядок использования:
//
// 1. Загрузите данный файл первым в качестве зависимости внутри вашего главного JavaScript-файла.
// 2. Как только HTML-страница будет загружена выполните в консоли браузера команды:
// window.rjs.buildTree();
// console.log(window.rjs.tree);
// В результате в объекте window.rjs.tree будет сформировано дерево зависимостей ваших модулей.
// 3. Для формирования списка зависимостей модулей вызовите метод window.rjs.toList().
//
// Методы доступные после загрузки HTML-страницы:
// rjs.buildTree()
// - Формирует карту зависимостей ваших модулей внутри объекта rjs.tree.
// - Выведите значение rjs.tree в консоли браузера, чтобы увидеть карту зависимостей модулей.
// rjs.toList()
// - Возвращает строку со списком зависимостей всех модулей.
// onResourceLoad - это внутренний крюк, который может быть использован для вывода сообщения о том, что модуль был
// создан или он экспортировал свое значение. Таким образом становится возможна отрисовка порядка загрузки модулей и их зависимостей.
requirejs.onResourceLoad = function (context, module, dependeciesArray) {
// context - внутренний объект, испольуемый RequireJS для хранения экспортированных значений и состояния загрузки модулей.
// В данном случае он никак не используется.
// module - объект содержащий информацию о только что загруженном модуле.
// Свойства объекта module:
// module.name - нормализованное имя модуля. Для плагина это просто имя плагина.
// module.url - URL исползуемый для загрузки файла модуля. Может быть относительным путем.
// dependeciesArray - массив зависимостей определенных для данного модуля. Каждый элемент массива это объект module.
// Сформировать глобальный объект window.rjs при загрузке первого модуля
if (!window.rjs) {
window.rjs = {
tree: {} // дерево зависимостей модулей
, buildTree: buildTree // функция формирования карты зависисмостей модулей (определена ниже)
, toList: toList // функция формирования списка зависисмостей модулей (определена ниже)
, toPaths: toPaths
, buildPathsTree: buildPathsTree
, getMainFileTree: getMainFileTree
, drawTree: drawTree
};
}
// Если модуля нет в дереве зависимостей, то добавить объект с данными нового модуля в дерево
if (!window.rjs.tree[module.name]) {
window.rjs.tree[module.name] = {moduleName: module.name, moduleDependeciesNames: [], moduleDependeciesTree: {}, modulePath: module.url ? module.url.split('?')[0] : ''};
// moduleDependeciesNames - массив имен модулей, от которых зависит данный модуль
// moduleMap - карта зависимостей данного модуля
}
// Для формирования полного дерева зависимостей модулей друг от друга
var i, len;
if (dependeciesArray) { // Если у модуля есть зависимости, то
for (
i = 0, len = dependeciesArray.length;
i < len;
i++
) { // добавить в массив имен зависимостей имена модулей, от которых зависит данный модуль
window.rjs.tree[module.name].moduleDependeciesNames.push(dependeciesArray[i].name);
}
}
// На данном этапе в дерево добавлены имена всех загруженных модулей.
// В массив имен зависимостей всех модулей добавлены имена модулей, от которых они зависят.
// Однако карта зависимостей у всех модулей пока пуста.
};
// Функция формирования карты дерева зависисмостей модулей
// На данном этапе карта зависимостей у всех модулей пока пуста.
// Поэтому данная функция заполняет занчения moduleMap для каждого модуля.
function buildTree () {
var tree = window.rjs.tree
, moduleName
, currentModule
, i
, len
, currentDependencyName;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
currentDependencyName = currentModule.moduleDependeciesNames[i]; // Взять имя текущей зависимости данного модуля
currentModule.moduleDependeciesTree[currentDependencyName] = tree[currentDependencyName]; // В карту данного модуля добавить объект текущего модуля из дерева
}
}
}
}
// Фунцкия формирования списка зависисмостей модулей
// Данная функция возвращает строку, состоящую из списка зависисмостей модулей
function toList () {
var list = []
, tree = window.rjs.tree
, moduleName
, currentModule
, i
, len;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
len = currentModule.moduleDependeciesNames.length;
if (len) {
for (i = 0; i < len; i++) {
list.push(moduleName + ' < ' + currentModule.moduleDependeciesNames[i]); // Добавить строку вида "moduleName > moduleDependecyName" для каждой зависимости данного модуля
}
} else {
list.push(currentModule.moduleName); // Добавить строку вида "moduleName" для данного модуля
}
}
}
list.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return list.join('\n');
}
// Фунцкия формирования списка путей к файлам модулей
// Данная функция возвращает строку, состоящую из списка путей к файлам модулей
function toPaths () {
var paths = []
, tree = window.rjs.tree
, moduleName
, currentModule;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
paths.push(
moduleName.search('.html') === -1
? currentModule.modulePath.replace('./', '')
: 'js/' + moduleName
); // Добавить строку вида "modulePath" для данного модуля
}
}
paths.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return paths.join('\n');
}
// Функция формирования дерева путей загрузки модулей
function buildPathsTree () {
var paths = []
, tree = window.rjs.tree
, moduleName
, currentModule;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
paths.push(
moduleName.search('.html') === -1
? currentModule.modulePath.replace('./', '')
: 'js/' + moduleName
); // Добавить строку вида "modulePath" для данного модуля
}
}
paths.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return convertArrayOfDelimitedStringsIntoHierarchicalObject(paths, '/');
}
// Функция конвертации массива с разграниченными строками в иерархическое дерево
function convertArrayOfDelimitedStringsIntoHierarchicalObject (input, delimiter) {
// input = ['Fred-Jim-Bob', 'Fred-Jim', 'Fred-Thomas-Rob', 'Fred'];
// delimiter = '-';
var output = []
, i, j, k
, inputLength
, chain, chainLength
, currentNode, currentNodeLength
, wantedNode
, lastNode
, newNode;
for (i = 0, inputLength = input.length; i < inputLength; i++) {
chain = input[i].split(delimiter);
currentNode = output;
for (j = 0, chainLength = chain.length; j < chainLength; j++) {
wantedNode = chain[j];
lastNode = currentNode;
for (k = 0, currentNodeLength = currentNode.length; k < currentNodeLength; k++) {
if (currentNode[k].name === wantedNode) {
currentNode = currentNode[k].dependecies;
break;
}
}
// If we couldn't find an item in this list of dependecies
// that has the right name, create one:
if (lastNode === currentNode) {
currentNode[k] = {name: wantedNode, dependecies: []};
newNode = currentNode[k];
currentNode = newNode.dependecies;
}
}
}
return output.length > 0 ? output[0] : {};
}
// Функция выбора главного файла
function getMainFileTree () {
function buildTreeObject (module) {
var treeObject = {
name: module.moduleName
, path: module.modulePath
, dependecies: []
};
for (var key in module.moduleDependeciesTree) {
treeObject.dependecies.push(buildTreeObject(module.moduleDependeciesTree[key]));
}
treeObject.dependecies.sort(function(a, b){
a = a.name;
b = b.name;
if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}
});
return treeObject;
}
return buildTreeObject(window.rjs.tree['main']);
}
// Функция отрисовки дерева зависимостей модулей
function drawTree (obj, prefix, options) {
if (typeof obj === 'string') {obj = {name: obj};}
if (prefix === undefined) {prefix = '';}
if (options === undefined) {options = {};}
function chr (s) {
var chars = {
'│' : '|',
'└' : '`',
'├' : '+',
'─' : '-',
'┬' : '-'
};
if (options.unicode === false) {
return chars[s];
} else {
return s;
}
};
var dependecies = obj.dependecies || []
, lines = (obj.name || '').split('\n')
, splitter = '\n' + prefix + (dependecies.length ? chr('│') : ' ') + ' ';
return prefix
+ lines.join(splitter) + '\n'
+ dependecies.map(function (module, index) {
var last = (index === dependecies.length - 1)
, more = (module.dependecies && module.dependecies.length)
, prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
return prefix
+ (last ? chr('└') : chr('├')) + chr('─')
+ (more ? chr('┬') : chr('─')) + ' '
+ drawTree(module, prefix_, options).slice(prefix.length + 2);
}).join('');
}
Файл index.js
require.config({
paths: {
onResourceLoad: 'lib/require/rjs'
, main: './main'
}
, urlArgs: '_=' + Math.random()
});
require(
[
'onResourceLoad'
, 'main'
]
, function(
onResourceLoad
, main
) {
main();
if (console && console.log) {
window.rjs.buildTree();
//for (var key in window.rjs.tree) {console.log(key);}
//console.log(window.rjs.toList());
console.log(window.rjs.drawTree(window.rjs.getMainFileTree()));
// console.log(window.rjs.toPaths());
console.log(window.rjs.drawTree(window.rjs.buildPathsTree()));
}
}
);
Файл main.js
require.config({
paths: {
FirstModule: 'app/first/controller'
, SecondModule: 'app/second/controller'
, ThirdModule: 'app/third/controller'
}
});
define(
[
'FirstModule'
, 'SecondModule'
, 'ThirdModule'
]
, function(
FirstModule
, SecondModule
, ThirdModule
) {
return function () {
FirstModule.init();
SecondModule.init();
ThirdModule.init();
};
}
);
// Порядок использования:
//
// 1. Загрузите данный файл первым в качестве зависимости внутри вашего главного JavaScript-файла.
// 2. Как только HTML-страница будет загружена выполните в консоли браузера команды:
// window.rjs.buildTree();
// console.log(window.rjs.tree);
// В результате в объекте window.rjs.tree будет сформировано дерево зависимостей ваших модулей.
// 3. Для формирования списка зависимостей модулей вызовите метод window.rjs.toList().
//
// Методы доступные после загрузки HTML-страницы:
// rjs.buildTree()
// - Формирует карту зависимостей ваших модулей внутри объекта rjs.tree.
// - Выведите значение rjs.tree в консоли браузера, чтобы увидеть карту зависимостей модулей.
// rjs.toList()
// - Возвращает строку со списком зависимостей всех модулей.
// onResourceLoad - это внутренний крюк, который может быть использован для вывода сообщения о том, что модуль был
// создан или он экспортировал свое значение. Таким образом становится возможна отрисовка порядка загрузки модулей и их зависимостей.
requirejs.onResourceLoad = function (context, module, dependeciesArray) {
// context - внутренний объект, испольуемый RequireJS для хранения экспортированных значений и состояния загрузки модулей.
// В данном случае он никак не используется.
// module - объект содержащий информацию о только что загруженном модуле.
// Свойства объекта module:
// module.name - нормализованное имя модуля. Для плагина это просто имя плагина.
// module.url - URL исползуемый для загрузки файла модуля. Может быть относительным путем.
// dependeciesArray - массив зависимостей определенных для данного модуля. Каждый элемент массива это объект module.
// Сформировать глобальный объект window.rjs при загрузке первого модуля
if (!window.rjs) {
window.rjs = {
tree: {} // дерево зависимостей модулей
, buildTree: buildTree // функция формирования карты зависисмостей модулей (определена ниже)
, toList: toList // функция формирования списка зависисмостей модулей (определена ниже)
, toPaths: toPaths
, buildPathsTree: buildPathsTree
, getMainFileTree: getMainFileTree
, drawTree: drawTree
};
}
// Если модуля нет в дереве зависимостей, то добавить объект с данными нового модуля в дерево
if (!window.rjs.tree[module.name]) {
window.rjs.tree[module.name] = {moduleName: module.name, moduleDependeciesNames: [], moduleDependeciesTree: {}, modulePath: module.url ? module.url.split('?')[0] : ''};
// moduleDependeciesNames - массив имен модулей, от которых зависит данный модуль
// moduleMap - карта зависимостей данного модуля
}
// Для формирования полного дерева зависимостей модулей друг от друга
var i, len;
if (dependeciesArray) { // Если у модуля есть зависимости, то
for (
i = 0, len = dependeciesArray.length;
i < len;
i++
) { // добавить в массив имен зависимостей имена модулей, от которых зависит данный модуль
window.rjs.tree[module.name].moduleDependeciesNames.push(dependeciesArray[i].name);
}
}
// На данном этапе в дерево добавлены имена всех загруженных модулей.
// В массив имен зависимостей всех модулей добавлены имена модулей, от которых они зависят.
// Однако карта зависимостей у всех модулей пока пуста.
};
// Функция формирования карты дерева зависисмостей модулей
// На данном этапе карта зависимостей у всех модулей пока пуста.
// Поэтому данная функция заполняет занчения moduleMap для каждого модуля.
function buildTree () {
var tree = window.rjs.tree
, moduleName
, currentModule
, i
, len
, currentDependencyName;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
currentDependencyName = currentModule.moduleDependeciesNames[i]; // Взять имя текущей зависимости данного модуля
currentModule.moduleDependeciesTree[currentDependencyName] = tree[currentDependencyName]; // В карту данного модуля добавить объект текущего модуля из дерева
}
}
}
}
// Фунцкия формирования списка зависисмостей модулей
// Данная функция возвращает строку, состоящую из списка зависисмостей модулей
function toList () {
var list = []
, tree = window.rjs.tree
, moduleName
, currentModule
, i
, len;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
len = currentModule.moduleDependeciesNames.length;
if (len) {
for (i = 0; i < len; i++) {
list.push(moduleName + ' < ' + currentModule.moduleDependeciesNames[i]); // Добавить строку вида "moduleName > moduleDependecyName" для каждой зависимости данного модуля
}
} else {
list.push(currentModule.moduleName); // Добавить строку вида "moduleName" для данного модуля
}
}
}
list.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return list.join('\n');
}
// Фунцкия формирования списка путей к файлам модулей
// Данная функция возвращает строку, состоящую из списка путей к файлам модулей
function toPaths () {
var paths = []
, tree = window.rjs.tree
, moduleName
, currentModule;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
paths.push(
moduleName.search('.html') === -1
? currentModule.modulePath.replace('./', '')
: 'js/' + moduleName
); // Добавить строку вида "modulePath" для данного модуля
}
}
paths.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return paths.join('\n');
}
// Функция формирования дерева путей загрузки модулей
function buildPathsTree () {
var paths = []
, tree = window.rjs.tree
, moduleName
, currentModule;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
paths.push(
moduleName.search('.html') === -1
? currentModule.modulePath.replace('./', '')
: 'js/' + moduleName
); // Добавить строку вида "modulePath" для данного модуля
}
}
paths.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return convertArrayOfDelimitedStringsIntoHierarchicalObject(paths, '/');
}
// Функция конвертации массива с разграниченными строками в иерархическое дерево
function convertArrayOfDelimitedStringsIntoHierarchicalObject (input, delimiter) {
// input = ['Fred-Jim-Bob', 'Fred-Jim', 'Fred-Thomas-Rob', 'Fred'];
// delimiter = '-';
var output = []
, i, j, k
, inputLength
, chain, chainLength
, currentNode, currentNodeLength
, wantedNode
, lastNode
, newNode;
for (i = 0, inputLength = input.length; i < inputLength; i++) {
chain = input[i].split(delimiter);
currentNode = output;
for (j = 0, chainLength = chain.length; j < chainLength; j++) {
wantedNode = chain[j];
lastNode = currentNode;
for (k = 0, currentNodeLength = currentNode.length; k < currentNodeLength; k++) {
if (currentNode[k].name === wantedNode) {
currentNode = currentNode[k].dependecies;
break;
}
}
// If we couldn't find an item in this list of dependecies
// that has the right name, create one:
if (lastNode === currentNode) {
currentNode[k] = {name: wantedNode, dependecies: []};
newNode = currentNode[k];
currentNode = newNode.dependecies;
}
}
}
return output.length > 0 ? output[0] : {};
}
// Функция выбора главного файла
function getMainFileTree () {
function buildTreeObject (module) {
var treeObject = {
name: module.moduleName
, path: module.modulePath
, dependecies: []
};
for (var key in module.moduleDependeciesTree) {
treeObject.dependecies.push(buildTreeObject(module.moduleDependeciesTree[key]));
}
treeObject.dependecies.sort(function(a, b){
a = a.name;
b = b.name;
if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}
});
return treeObject;
}
return buildTreeObject(window.rjs.tree['main']);
}
// Функция отрисовки дерева зависимостей модулей
function drawTree (obj, prefix, options) {
if (typeof obj === 'string') {obj = {name: obj};}
if (prefix === undefined) {prefix = '';}
if (options === undefined) {options = {};}
function chr (s) {
var chars = {
'│' : '|',
'└' : '`',
'├' : '+',
'─' : '-',
'┬' : '-'
};
if (options.unicode === false) {
return chars[s];
} else {
return s;
}
};
var dependecies = obj.dependecies || []
, lines = (obj.name || '').split('\n')
, splitter = '\n' + prefix + (dependecies.length ? chr('│') : ' ') + ' ';
return prefix
+ lines.join(splitter) + '\n'
+ dependecies.map(function (module, index) {
var last = (index === dependecies.length - 1)
, more = (module.dependecies && module.dependecies.length)
, prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
return prefix
+ (last ? chr('└') : chr('├')) + chr('─')
+ (more ? chr('┬') : chr('─')) + ' '
+ drawTree(module, prefix_, options).slice(prefix.length + 2);
}).join('');
}
Файл index.js
require.config({
paths: {
onResourceLoad: 'lib/require/rjs'
, main: './main'
}
, urlArgs: '_=' + Math.random()
});
require(
[
'onResourceLoad'
, 'main'
]
, function(
onResourceLoad
, main
) {
main();
if (console && console.log) {
window.rjs.buildTree();
//for (var key in window.rjs.tree) {console.log(key);}
//console.log(window.rjs.toList());
console.log(window.rjs.drawTree(window.rjs.getMainFileTree()));
// console.log(window.rjs.toPaths());
console.log(window.rjs.drawTree(window.rjs.buildPathsTree()));
}
}
);
Файл main.js
require.config({
paths: {
FirstModule: 'app/first/controller'
, SecondModule: 'app/second/controller'
, ThirdModule: 'app/third/controller'
}
});
define(
[
'FirstModule'
, 'SecondModule'
, 'ThirdModule'
]
, function(
FirstModule
, SecondModule
, ThirdModule
) {
return function () {
FirstModule.init();
SecondModule.init();
ThirdModule.init();
};
}
);
пятница, 5 июня 2015 г.
JavaScript Build Require JS Tree Visualization
Файл rjs.js
// Порядок использования:
//
// 1. Загрузите данный файл первым в качестве зависимости внутри вашего главного JavaScript-файла.
// (Подробнее смотрите на странице https://github.com/jrburke/requirejs/wiki/Internal-API:-onResourceLoad)
// 2. Как только HTML-страница будет загружена выполните в консоли браузера команды:
// window.rjs.buildTree();
// console.log(window.rjs.tree);
// В результате в объекте window.rjs.tree будет сформировано дерево зависимостей ваших модулей.
// 3. Для формирования дерева зависимостей модулей в формате UML вызовите метод window.rjs.toUml().
// Результат работы метода вы можете использовать здесь: http://yuml.me/diagram/scruffy/class/draw
//
// Методы доступные после загрузки HTML-страницы:
// rjs.buildTree()
// - Формирует карту зависимостей ваших модулей внутри объекта rjs.tree.
// - Выведите значение rjs.tree в консоли браузера, чтобы увидеть карту зависимостей модулей.
// rjs.toUml()
// - Возвращает строку в формате UML, которая может быть использована для построения UML-диаграммы.
// - UML Website: http://yuml.me/diagram/scruffy/class/draw
// onResourceLoad - это внутренний крюк, который может быть использован для вывода сообщения о том, что модуль был
// создан или он экспортировал свое значение. Таким образом становится возможна отрисовка порядка загрузки модулей и их зависимостей.
requirejs.onResourceLoad = function (context, module, dependeciesArray) {
// context - внутренний объект, испольуемый RequireJS для хранения экспортированных значений и состояния загрузки модулей
// В данном случае он никак не используется.
// module - объект содержащий информацию о только что загруженном модуле.
// Свойства объекта module:
// module.name - нормализованное имя модуля. Для плагина это просто имя плагина.
// module.parentMap - объект модуля, используемый для решения задачи относительных ID для данного модуля. Может быть null, но если существует, то имеет ту же структуру, что и объект module.
// Дополнительно можно использовать следующие свойства объекта module:
// module.url - URL исползуемый для загрузки файла модуля. Может быть относительным путем.
// dependeciesArray - массив зависимостей определенных для данного модуля. Каждый элемент массива это объект module.
// Сформировать глобальный объект window.rjs при загрузке первого модуля
if (!window.rjs) {
window.rjs = {
tree: {} // дерево зависимостей модулей
, buildTree: buildTree // функция формирования карты зависисмостей модулей (определена ниже)
, toUml: toUml // функция формирования дерева зависисмостей модулей в формате UML (определена ниже)
};
}
// Если модуля нет в дереве зависимостей, то добавить объект с данными нового модуля в дерево
if (!window.rjs.tree[module.name]) {
window.rjs.tree[module.name] = {moduleDependeciesNames: [], moduleMap: {}};
// moduleDependeciesNames - массив имен модулей, от которых зависит данный модуль
// moduleMap - карта зависимостей данного модуля
}
// Для формирования полного дерева зависимостей модулей друг от друга
var i, len;
if (dependeciesArray) { // Если у модуля есть зависимости, то
for (
i = 0, len = dependeciesArray.length;
i < len;
i++
) { // добавить в массив имен зависимостей имена модулей, от которых зависит данный модуль
window.rjs.tree[module.name].moduleDependeciesNames.push(dependeciesArray[i].name);
}
}
// На данном этапе в дерево добавлены имена всех загруженных модулей.
// В массив имен зависимостей всех модулей добавлены имена модулей, от которых они зависят.
// Однако карта зависимостей у всех модулей пока пуста.
// Для формирования простого дерева зависимостей данного модуля
// if (module.parentMap && module.parentMap.name) {
// if (!window.rjs.tree[module.parentMap.name]) {
// window.rjs.tree[module.parentMap.name] = {moduleDependeciesNames: [], moduleMap: {}};
// }
// if (module.parentMap.name !== module.name) {
// window.rjs.tree[module.parentMap.name].moduleDependeciesNames.push(module.name);
// }
// }
};
// Функция формирования карты дерева зависисмостей модулей
// На данном этапе карта зависимостей у всех модулей пока пуста.
// Поэтому данная функция заполняет занчения moduleMap для каждого модуля.
function buildTree () {
var tree = window.rjs.tree
, moduleName
, currentModule
, i
, len
, currentDependencyName;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleDependeciesNames: [], moduleMap: {}}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
currentDependencyName = currentModule.moduleDependeciesNames[i]; // Взять имя текущей зависимости данного модуля
currentModule.moduleMap[currentDependencyName] = tree[currentDependencyName]; // В карту данного модуля добавить объект текущего модуля из дерева
}
}
}
}
// Фунцкия формирования дерева зависисмостей модулей в формате UML
function toUml () {
var uml = []
, tree = window.rjs.tree
, moduleName
, currentModule
, i
, len;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleDependeciesNames: [], moduleMap: {}}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
uml.push('[' + moduleName + ']->[' + currentModule.moduleDependeciesNames[i] + ']'); // Добавить строку вида [moduleName]->[moduleDependecyName] для каждой зависимости данного модуля
}
}
}
return uml.join('\n');
}
Файл index.js
require.config({
paths: {
onResourceLoad: 'lib/require/rjs'
, FirstModule: 'app/first/controller'
, SecondModule: 'app/second/controller'
, ThirdModule: 'app/third/controller'
}
});
require(
[
'onResourceLoad'
, 'FirstModule'
, 'SecondModule'
, 'ThirdModule'
]
, function(
onResourceLoad
, FirstModule
, SecondModule
, ThirdModule
) {
FirstModule.init();
SecondModule.init();
ThirdModule.init();
}
);
// Порядок использования:
//
// 1. Загрузите данный файл первым в качестве зависимости внутри вашего главного JavaScript-файла.
// (Подробнее смотрите на странице https://github.com/jrburke/requirejs/wiki/Internal-API:-onResourceLoad)
// 2. Как только HTML-страница будет загружена выполните в консоли браузера команды:
// window.rjs.buildTree();
// console.log(window.rjs.tree);
// В результате в объекте window.rjs.tree будет сформировано дерево зависимостей ваших модулей.
// 3. Для формирования дерева зависимостей модулей в формате UML вызовите метод window.rjs.toUml().
// Результат работы метода вы можете использовать здесь: http://yuml.me/diagram/scruffy/class/draw
//
// Методы доступные после загрузки HTML-страницы:
// rjs.buildTree()
// - Формирует карту зависимостей ваших модулей внутри объекта rjs.tree.
// - Выведите значение rjs.tree в консоли браузера, чтобы увидеть карту зависимостей модулей.
// rjs.toUml()
// - Возвращает строку в формате UML, которая может быть использована для построения UML-диаграммы.
// - UML Website: http://yuml.me/diagram/scruffy/class/draw
// onResourceLoad - это внутренний крюк, который может быть использован для вывода сообщения о том, что модуль был
// создан или он экспортировал свое значение. Таким образом становится возможна отрисовка порядка загрузки модулей и их зависимостей.
requirejs.onResourceLoad = function (context, module, dependeciesArray) {
// context - внутренний объект, испольуемый RequireJS для хранения экспортированных значений и состояния загрузки модулей
// В данном случае он никак не используется.
// module - объект содержащий информацию о только что загруженном модуле.
// Свойства объекта module:
// module.name - нормализованное имя модуля. Для плагина это просто имя плагина.
// module.parentMap - объект модуля, используемый для решения задачи относительных ID для данного модуля. Может быть null, но если существует, то имеет ту же структуру, что и объект module.
// Дополнительно можно использовать следующие свойства объекта module:
// module.url - URL исползуемый для загрузки файла модуля. Может быть относительным путем.
// dependeciesArray - массив зависимостей определенных для данного модуля. Каждый элемент массива это объект module.
// Сформировать глобальный объект window.rjs при загрузке первого модуля
if (!window.rjs) {
window.rjs = {
tree: {} // дерево зависимостей модулей
, buildTree: buildTree // функция формирования карты зависисмостей модулей (определена ниже)
, toUml: toUml // функция формирования дерева зависисмостей модулей в формате UML (определена ниже)
};
}
// Если модуля нет в дереве зависимостей, то добавить объект с данными нового модуля в дерево
if (!window.rjs.tree[module.name]) {
window.rjs.tree[module.name] = {moduleDependeciesNames: [], moduleMap: {}};
// moduleDependeciesNames - массив имен модулей, от которых зависит данный модуль
// moduleMap - карта зависимостей данного модуля
}
// Для формирования полного дерева зависимостей модулей друг от друга
var i, len;
if (dependeciesArray) { // Если у модуля есть зависимости, то
for (
i = 0, len = dependeciesArray.length;
i < len;
i++
) { // добавить в массив имен зависимостей имена модулей, от которых зависит данный модуль
window.rjs.tree[module.name].moduleDependeciesNames.push(dependeciesArray[i].name);
}
}
// На данном этапе в дерево добавлены имена всех загруженных модулей.
// В массив имен зависимостей всех модулей добавлены имена модулей, от которых они зависят.
// Однако карта зависимостей у всех модулей пока пуста.
// Для формирования простого дерева зависимостей данного модуля
// if (module.parentMap && module.parentMap.name) {
// if (!window.rjs.tree[module.parentMap.name]) {
// window.rjs.tree[module.parentMap.name] = {moduleDependeciesNames: [], moduleMap: {}};
// }
// if (module.parentMap.name !== module.name) {
// window.rjs.tree[module.parentMap.name].moduleDependeciesNames.push(module.name);
// }
// }
};
// Функция формирования карты дерева зависисмостей модулей
// На данном этапе карта зависимостей у всех модулей пока пуста.
// Поэтому данная функция заполняет занчения moduleMap для каждого модуля.
function buildTree () {
var tree = window.rjs.tree
, moduleName
, currentModule
, i
, len
, currentDependencyName;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleDependeciesNames: [], moduleMap: {}}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
currentDependencyName = currentModule.moduleDependeciesNames[i]; // Взять имя текущей зависимости данного модуля
currentModule.moduleMap[currentDependencyName] = tree[currentDependencyName]; // В карту данного модуля добавить объект текущего модуля из дерева
}
}
}
}
// Фунцкия формирования дерева зависисмостей модулей в формате UML
function toUml () {
var uml = []
, tree = window.rjs.tree
, moduleName
, currentModule
, i
, len;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleDependeciesNames: [], moduleMap: {}}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
uml.push('[' + moduleName + ']->[' + currentModule.moduleDependeciesNames[i] + ']'); // Добавить строку вида [moduleName]->[moduleDependecyName] для каждой зависимости данного модуля
}
}
}
return uml.join('\n');
}
Файл index.js
require.config({
paths: {
onResourceLoad: 'lib/require/rjs'
, FirstModule: 'app/first/controller'
, SecondModule: 'app/second/controller'
, ThirdModule: 'app/third/controller'
}
});
require(
[
'onResourceLoad'
, 'FirstModule'
, 'SecondModule'
, 'ThirdModule'
]
, function(
onResourceLoad
, FirstModule
, SecondModule
, ThirdModule
) {
FirstModule.init();
SecondModule.init();
ThirdModule.init();
}
);
четверг, 4 июня 2015 г.
JavaScript Build Folder Tree Visualization
var fs = require('fs') // file system module
, path = require('path'); // file path module
// Function dirTree() returns json tree of directory structure
function dirTree (rootDirectoryPath) {
rootDirectoryPath = rootDirectoryPath.replace(/\/+$/ , ''); // clean trailing '/'(s)
var directoryElement
, treeObject;
if (fs.existsSync(rootDirectoryPath)) {directoryElement = fs.lstatSync(rootDirectoryPath); // extract tree element if root exists
} else {return 'Error: root does not exist.';
}
// tree treeObjectect info
var treeObject = {
path: rootDirectoryPath
, name: path.basename(rootDirectoryPath)
, type: 'unknown'
, children: []
};
if (directoryElement.isDirectory()) {
// execute for each child and call tree recursively
treeObject.children = fs.readdirSync(rootDirectoryPath).map(function(child){return dirTree(rootDirectoryPath + '/' + child);});
treeObject.type = 'folder';
} else if (directoryElement.isFile()) { treeObject.type = 'file';
} else if (directoryElement.isSymbolicLink()) {treeObject.type = 'link';
} else { treeObject.type = 'unknown';
}
return treeObject; // return tree
}
/*
// Пример использования dirTree()
console.log(JSON.stringify(dirTree('./node_modules')));
console.log(dirTree('./node_modules'));
*/
// hierarchy(obj, prefix='', opts={})
// Функция 'hierarchy' возвращает строку, представляющую из себя иерархию элементов объекта 'obj', соединенных с помощью символов труб в формате Unicode.
// 'obj' должен представлять из себя дерево, состоящее из вложенных друг в друга объектов, имеющих метки 'name' и массивы узлов 'children'.
// 'name' - это строка с текстом, который выводится на соотвествующем уровне узла, а 'children' - это массив зависимостей текущего узла.
// Если узел является строкой, то эта строка будет использована в качестве метки 'name', а вместо узла 'children' для нее будет использован пустой массив.
// 'prefix' - это строка, которая вставляется перед основным содержимым на каждом шаге сформированного графа. Используется внутри алгоритма рекурсивного обхода дерева.
// Если метка 'name' имеет внутри себя символы перехода на новую строку (\n), то в этом случае они будут использованы в качестве перехода на новую строку в месте вывода текста метки, учитывая текущий отступ и 'prefix' на данному уровне.
// Для отключения вывода результата выполнения функции в формате Unicode при предпочтении вывода результата в формате ANSI установите значение opts.unicode в false.
function hierarchy (obj, prefix, opts) {
if (prefix === undefined) {prefix = '';}
if (!opts) {opts = {};}
function chr (s) {
var chars = {
'│' : '|',
'└' : '`',
'├' : '+',
'─' : '-',
'┬' : '-'
};
return opts.unicode === false ? chars[s] : s;
};
if (typeof obj === 'string') {
obj = {name: obj};
}
var children = obj.children || []
, lines = (obj.name || '').split('\n')
, splitter = '\n' + prefix + (children.length ? chr('│') : ' ') + ' ';
return prefix
+ lines.join(splitter) + '\n'
+ children.map(function (child, ix) {
var last = ix === children.length - 1
, more = child.children && child.children.length
, prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
return prefix
+ (last ? chr('└') : chr('├')) + chr('─')
+ (more ? chr('┬') : chr('─')) + ' '
+ hierarchy(child, prefix_, opts).slice(prefix.length + 2);
}).join('');
}
/*
// Пример использования hierarchy() без префикса 'prefix' и опций 'opts'
var result = hierarchy(
{
name: 'beep'
, children: [
'ity'
, {
name: 'boop'
, children: [
{
name: 'o_O'
, children: [
{
name: 'oh'
, children: [
'hello'
, 'puny'
]
}
, 'human'
]
}
, 'party\ntime!'
]
}
]
}
);
console.log(result);
// beep
// ├── ity
// └─┬ boop
// ├─┬ o_O
// │ ├─┬ oh
// │ │ ├── hello
// │ │ └── puny
// │ └── human
// └── party
// time!
// Пример использования hierarchy() с префиксом 'prefix' и опциями 'opts'
var result = hierarchy(
{
name: 'beep'
, children: [
'ity'
, {
name: 'boop'
, children: [
{
name: 'o_O'
, children: [
{
name: 'oh'
, children: [
'hello'
, 'puny'
]
}
, 'human'
]
}
, 'party\ntime!'
]
}
]
}
, '...'
, {unicode: false}
);
console.log(result);
// ...beep
// ...+-- ity
// ...`-- boop
// ... +-- o_O
// ... | +-- oh
// ... | | +-- hello
// ... | | `-- puny
// ... | `-- human
// ... `-- party
// ... time!
*/
console.log(hierarchy(dirTree('./node_modules')));
/*
if (module.parent === undefined) {
// child dirTree.js ~/foo/bar
var util = require('util');
console.log(util.inspect(dirTree(process.argv[2]), false, null));
}
*/
, path = require('path'); // file path module
// Function dirTree() returns json tree of directory structure
function dirTree (rootDirectoryPath) {
rootDirectoryPath = rootDirectoryPath.replace(/\/+$/ , ''); // clean trailing '/'(s)
var directoryElement
, treeObject;
if (fs.existsSync(rootDirectoryPath)) {directoryElement = fs.lstatSync(rootDirectoryPath); // extract tree element if root exists
} else {return 'Error: root does not exist.';
}
// tree treeObjectect info
var treeObject = {
path: rootDirectoryPath
, name: path.basename(rootDirectoryPath)
, type: 'unknown'
, children: []
};
if (directoryElement.isDirectory()) {
// execute for each child and call tree recursively
treeObject.children = fs.readdirSync(rootDirectoryPath).map(function(child){return dirTree(rootDirectoryPath + '/' + child);});
treeObject.type = 'folder';
} else if (directoryElement.isFile()) { treeObject.type = 'file';
} else if (directoryElement.isSymbolicLink()) {treeObject.type = 'link';
} else { treeObject.type = 'unknown';
}
return treeObject; // return tree
}
/*
// Пример использования dirTree()
console.log(JSON.stringify(dirTree('./node_modules')));
console.log(dirTree('./node_modules'));
*/
// hierarchy(obj, prefix='', opts={})
// Функция 'hierarchy' возвращает строку, представляющую из себя иерархию элементов объекта 'obj', соединенных с помощью символов труб в формате Unicode.
// 'obj' должен представлять из себя дерево, состоящее из вложенных друг в друга объектов, имеющих метки 'name' и массивы узлов 'children'.
// 'name' - это строка с текстом, который выводится на соотвествующем уровне узла, а 'children' - это массив зависимостей текущего узла.
// Если узел является строкой, то эта строка будет использована в качестве метки 'name', а вместо узла 'children' для нее будет использован пустой массив.
// 'prefix' - это строка, которая вставляется перед основным содержимым на каждом шаге сформированного графа. Используется внутри алгоритма рекурсивного обхода дерева.
// Если метка 'name' имеет внутри себя символы перехода на новую строку (\n), то в этом случае они будут использованы в качестве перехода на новую строку в месте вывода текста метки, учитывая текущий отступ и 'prefix' на данному уровне.
// Для отключения вывода результата выполнения функции в формате Unicode при предпочтении вывода результата в формате ANSI установите значение opts.unicode в false.
function hierarchy (obj, prefix, opts) {
if (prefix === undefined) {prefix = '';}
if (!opts) {opts = {};}
function chr (s) {
var chars = {
'│' : '|',
'└' : '`',
'├' : '+',
'─' : '-',
'┬' : '-'
};
return opts.unicode === false ? chars[s] : s;
};
if (typeof obj === 'string') {
obj = {name: obj};
}
var children = obj.children || []
, lines = (obj.name || '').split('\n')
, splitter = '\n' + prefix + (children.length ? chr('│') : ' ') + ' ';
return prefix
+ lines.join(splitter) + '\n'
+ children.map(function (child, ix) {
var last = ix === children.length - 1
, more = child.children && child.children.length
, prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
return prefix
+ (last ? chr('└') : chr('├')) + chr('─')
+ (more ? chr('┬') : chr('─')) + ' '
+ hierarchy(child, prefix_, opts).slice(prefix.length + 2);
}).join('');
}
/*
// Пример использования hierarchy() без префикса 'prefix' и опций 'opts'
var result = hierarchy(
{
name: 'beep'
, children: [
'ity'
, {
name: 'boop'
, children: [
{
name: 'o_O'
, children: [
{
name: 'oh'
, children: [
'hello'
, 'puny'
]
}
, 'human'
]
}
, 'party\ntime!'
]
}
]
}
);
console.log(result);
// beep
// ├── ity
// └─┬ boop
// ├─┬ o_O
// │ ├─┬ oh
// │ │ ├── hello
// │ │ └── puny
// │ └── human
// └── party
// time!
// Пример использования hierarchy() с префиксом 'prefix' и опциями 'opts'
var result = hierarchy(
{
name: 'beep'
, children: [
'ity'
, {
name: 'boop'
, children: [
{
name: 'o_O'
, children: [
{
name: 'oh'
, children: [
'hello'
, 'puny'
]
}
, 'human'
]
}
, 'party\ntime!'
]
}
]
}
, '...'
, {unicode: false}
);
console.log(result);
// ...beep
// ...+-- ity
// ...`-- boop
// ... +-- o_O
// ... | +-- oh
// ... | | +-- hello
// ... | | `-- puny
// ... | `-- human
// ... `-- party
// ... time!
*/
console.log(hierarchy(dirTree('./node_modules')));
/*
if (module.parent === undefined) {
// child dirTree.js ~/foo/bar
var util = require('util');
console.log(util.inspect(dirTree(process.argv[2]), false, null));
}
*/
вторник, 2 июня 2015 г.
JavaScript File Download
<!DOCTYPE html>
<html>
<head>
<title>JavaScript File Download</title>
</head>
<body>
<script type="text/javascript">
function saveAs (fileContents, fileName) {
fileContents = 'data:text/plain;charset=utf-8;headers=Content-Disposition%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0A,' + escape(fileContents);
var downloadWindow
, link = document.createElement('a');
// For non-IE
if (! window.ActiveXObject && typeof link.download === 'string') {
document.body.appendChild(link); // Firefox requires the link to be in the body
link.download = fileName;
link.href = fileContents;
link.target = '_blank';
link.click(); // simulate click
document.body.removeChild(link); // remove the link when done
} else if (!! window.ActiveXObject && document.execCommand) {
// For IE
window.open(fileContents, '_blank');
document.execCommand('SaveAs', true, fileName || fileContents);
document.close();
}
}
saveAs('Text', 'File.txt');
</script>
</body>
</html>
<html>
<head>
<title>JavaScript File Download</title>
</head>
<body>
<script type="text/javascript">
function saveAs (fileContents, fileName) {
fileContents = 'data:text/plain;charset=utf-8;headers=Content-Disposition%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0A,' + escape(fileContents);
var downloadWindow
, link = document.createElement('a');
// For non-IE
if (! window.ActiveXObject && typeof link.download === 'string') {
document.body.appendChild(link); // Firefox requires the link to be in the body
link.download = fileName;
link.href = fileContents;
link.target = '_blank';
link.click(); // simulate click
document.body.removeChild(link); // remove the link when done
} else if (!! window.ActiveXObject && document.execCommand) {
// For IE
window.open(fileContents, '_blank');
document.execCommand('SaveAs', true, fileName || fileContents);
document.close();
}
}
saveAs('Text', 'File.txt');
</script>
</body>
</html>
Подписаться на:
Сообщения (Atom)