hookable-tree v1.1.0
Tree.js 
Tree.js is a JavaScript library to build and manipulate hookable trees.
Installation
It is available with bower:
bower install tree.jsThen add the retrieved files to your HTML layout:
<script type="text/javascript" src="/path/to/bower_components/tree.js/tree.min.js"></script>
<!-- If you want to build hookable tree (see below) -->
<script type="text/javascript" src="/path/to/bower_components/q/q.js"></script>You can also use it with RequireJS as an AMD module.
Usage
Simple tree
Create a tree
var myTree = Tree.tree({
children: [
{
name: 'dupuis',
children: [
{
name: 'prunelle',
children: [
{
name: 'lebrac',
job: 'designer'
},
{
name: 'lagaffe',
firstname: 'gaston',
job: 'sleeper'
},
]
}
]
}
]
});Find a node
var lebrac = myTree.find('/dupuis/prunelle/lebrac');
// or
var lebrac = myTree.find('/dupuis').find('/prunelle/lebrac');
// or
var lebrac = myTree.find('/dupuis').find('/prunelle').find('/lebrac');Get the raw data of a node
lebrac.data() // { name: 'lebrac', job: 'designer' }Get an attribute
lebrac.attr('job'); // designerSet an attribute
lebrac.attr('job', 'director');
lebrac
.attr('location', 'here')
.attr('hobby', 'design');Get the path of a node
lebrac.path(); // /dupuis/prunelle/lebracGet the parent of a node
var dupuis = lebrac.parent();
dupuis.name(); // dupuis
dupuis.parent(); // undefinedAppend a child node
lebrac.append(Tree.tree({
name: 'paper',
children: [{ name: 'pen' }]
}));
lebrac.find('/paper/pen');
lebrac.find('/paper').parent().parent().parent().name(); // dupuisRemove a node
lebrac.remove();
myTree.find('/dupuis/prunelle/lebrac'); // undefinedMove a node
var lagaffe = myTree.find('/dupuis/prunelle/lagaffe').moveTo(myTree.find('/dupuis'));
lagaffe.path(); // /dupuis/lagaffeGet the children of a node
var children = myTree.find('/dupuis').children();
children[0].name(); // prunelleGet a node visitor
In order to execute a callback on each node of the tree, you can use a visitor:
var visitor = myTree.visitor();
visitor(function(node) {
// you can now interact with each node
});Stringify a node
On any node you can call stringify to serialize it. Internally it will use JSON.stringify with custom replacer to avoid circular references because of the _parent private property:
myTree.stringify()Work with hooks
To work with hooks, you first need to add hook capacities to your tree:
var hookableTree = Tree.hookable(myTree);Everything explained above is still true but the hookable operations will now return promises!
Because of that you need to include into your page Q library. Otherwise you can specify another promises library by calling: hookableTree.promiseFactory(YOUR_FACTORY). It must expose the same API than Q.
You can configure the timeout used for each listener by calling hookableTree.timeout(30000). Set it to 0 to disable it, default to 30000.
Register a hook listener
There are 12 hooks available:
| Hook | Description |
|---|---|
| HOOK_PRE_APPEND | Triggered when append is called and before applying it on the tree |
| HOOK_POST_APPEND | Triggered when append is called and after applying it on the tree |
| HOOK_ERROR_APPEND | Triggered when append is called and an error occured |
| HOOK_PRE_REMOVE | Triggered when remove is called and before applying it on the tree |
| HOOK_POST_REMOVE | Triggered when remove is called and after applying it on the tree |
| HOOK_ERROR_REMOVE | Triggered when remove is called and an error occured |
| HOOK_PRE_MOVE | Triggered when moveTo is called and before applying it on the tree |
| HOOK_POST_MOVE | Triggered when moveTo is called and after applying it on the tree |
| HOOK_ERROR_MOVE | Triggered when moveTo is called and an error occured |
| HOOK_PRE_CLONE | Triggered when clone is called and before applying it on the tree |
| HOOK_POST_CLONE | Triggered when clone is called and after applying it on the tree |
| HOOK_ERROR_CLONE | Triggered when clone is called and an error occured |
To register a hook you need to call registerListener(string hook, function listener):
hookableTree.registerListener(hookableTree.HOOK_PRE_APPEND, function(newNode) {
// I am a hook listener, I will be triggered before any append operation.
// The arguments are not always the same depending on the hook.
// Hook context is the tree.
this; // will be our tree
// If you need to perform asynchronous operation, just return a promise.
});Because of hooks, append, remove, move, clone will return promise, as show in this example:
hookableTree.append(Tree.tree({ name: 'spirou'})).then(function(childNode) {
// Everything is ok, it worked!
// When you append a node, you can either give as argument a tree or hookable tree.
// If it is a hookable tree, its hook listeners will added to the parent tree.
}, function(err) {
// An error occured or a hook listener failed
});hookableTree.find('/dupuis').remove().then(function(dupuisParent) {
// Everything is ok, it worked!
}, function(err) {
// An error occured or a hook listener failed
});hookableTree.find('/dupuis/prunelle').moveTo(hookableTree).then(function(prunelle) {
// Everything is ok, it worked!
}, function(err) {
// An error occured or a hook listener failed
});hookableTree.find('/dupuis/prunelle').clone().then(function(clonedPrunelle) {
// Everything is ok, it worked!
}, function(err) {
// An error occured or a hook listener failed
});Build
To rebuild the minified JavaScript you must run: make build.
Tests
Install dependencies and run the unit tests:
make install
make test-specContributing
All contributions are welcome and must pass the tests. If you add a new feature, please write tests for it.
License
This application is available under the MIT License, courtesy of marmelab.
10 years ago