Add backlinks indexer (#4421)

* Add tests for backlinks

* Add backlinks indexer

* Use backlinks indexer in getTiddlerBacklinks if available

* Extract link extraction into its own method

This way we can provide an arbitrary parse tree, rather than just a
title, which will allow us to compare lists of outgoing links between
versions of a single tiddler

* Use new extractLinks method in backlinks indexer

...rather than copy-pasting the implementation

* Remove ES6-isms

TiddlyWiki needs to work with browsers that only support ES5
This commit is contained in:
Rob Hoelz
2020-03-26 08:15:02 -05:00
committed by GitHub
parent 2d9a9703cb
commit ae04a425c0
3 changed files with 255 additions and 24 deletions

View File

@@ -414,6 +414,30 @@ exports.forEachTiddler = function(/* [options,]callback */) {
}
};
/*
Return an array of tiddler titles that are directly linked within the given parse tree
*/
exports.extractLinks = function(parseTreeRoot) {
// Count up the links
var links = [],
checkParseTree = function(parseTree) {
for(var t=0; t<parseTree.length; t++) {
var parseTreeNode = parseTree[t];
if(parseTreeNode.type === "link" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === "string") {
var value = parseTreeNode.attributes.to.value;
if(links.indexOf(value) === -1) {
links.push(value);
}
}
if(parseTreeNode.children) {
checkParseTree(parseTreeNode.children);
}
}
};
checkParseTree(parseTreeRoot);
return links;
};
/*
Return an array of tiddler titles that are directly linked from the specified tiddler
*/
@@ -423,26 +447,10 @@ exports.getTiddlerLinks = function(title) {
return this.getCacheForTiddler(title,"links",function() {
// Parse the tiddler
var parser = self.parseTiddler(title);
// Count up the links
var links = [],
checkParseTree = function(parseTree) {
for(var t=0; t<parseTree.length; t++) {
var parseTreeNode = parseTree[t];
if(parseTreeNode.type === "link" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === "string") {
var value = parseTreeNode.attributes.to.value;
if(links.indexOf(value) === -1) {
links.push(value);
}
}
if(parseTreeNode.children) {
checkParseTree(parseTreeNode.children);
}
}
};
if(parser) {
checkParseTree(parser.tree);
return self.extractLinks(parser.tree);
}
return links;
return [];
});
};
@@ -451,13 +459,18 @@ Return an array of tiddler titles that link to the specified tiddler
*/
exports.getTiddlerBacklinks = function(targetTitle) {
var self = this,
backlinksIndexer = this.getIndexer("BacklinksIndexer"),
backlinks = backlinksIndexer && backlinksIndexer.lookup(targetTitle);
if(!backlinks) {
backlinks = [];
this.forEachTiddler(function(title,tiddler) {
var links = self.getTiddlerLinks(title);
if(links.indexOf(targetTitle) !== -1) {
backlinks.push(title);
}
});
this.forEachTiddler(function(title,tiddler) {
var links = self.getTiddlerLinks(title);
if(links.indexOf(targetTitle) !== -1) {
backlinks.push(title);
}
});
}
return backlinks;
};