[6a3a178] | 1 | const Node = require('./node');
|
---|
| 2 |
|
---|
| 3 | class Container extends Node {
|
---|
| 4 | walk(callback) {
|
---|
| 5 | return this.each((child, i) => {
|
---|
| 6 | let result = callback(child, i);
|
---|
| 7 | if (result !== false && child.walk) {
|
---|
| 8 | result = child.walk(callback);
|
---|
| 9 | }
|
---|
| 10 | return result;
|
---|
| 11 | });
|
---|
| 12 | }
|
---|
| 13 |
|
---|
| 14 | walkType(type, callback) {
|
---|
| 15 | if (!type || !callback) {
|
---|
| 16 | throw new Error('Parameters {type} and {callback} are required.');
|
---|
| 17 | }
|
---|
| 18 |
|
---|
| 19 | // allow users to pass a constructor, or node type string; eg. Word.
|
---|
| 20 | const isTypeCallable = typeof type === 'function';
|
---|
| 21 |
|
---|
| 22 | return this.walk((node, index) => {
|
---|
| 23 | if ((isTypeCallable && node instanceof type) || (!isTypeCallable && node.type === type)) {
|
---|
| 24 | return callback.call(this, node, index);
|
---|
| 25 | }
|
---|
| 26 | });
|
---|
| 27 | }
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | Container.registerWalker = (constructor) => {
|
---|
| 31 | let walkerName = `walk${constructor.name}`;
|
---|
| 32 |
|
---|
| 33 | // plural sugar
|
---|
| 34 | if (walkerName.lastIndexOf('s') !== walkerName.length - 1) {
|
---|
| 35 | walkerName += 's';
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | if (Container.prototype[walkerName]) {
|
---|
| 39 | return;
|
---|
| 40 | }
|
---|
| 41 |
|
---|
| 42 | // we need access to `this` so we can't use an arrow function
|
---|
| 43 | Container.prototype[walkerName] = function(callback) {
|
---|
| 44 | return this.walkType(constructor, callback);
|
---|
| 45 | };
|
---|
| 46 | };
|
---|
| 47 |
|
---|
| 48 | module.exports = Container;
|
---|