diff --git a/core/modules/indexers/backlinks-index.js b/core/modules/indexers/backlinks-index.js new file mode 100644 index 000000000..5902e2829 --- /dev/null +++ b/core/modules/indexers/backlinks-index.js @@ -0,0 +1,86 @@ +/*\ +title: $:/core/modules/indexers/backlinks-indexer.js +type: application/javascript +module-type: indexer + +Indexes the tiddlers' backlinks + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global modules: false */ +"use strict"; + + +function BacklinksIndexer(wiki) { + this.wiki = wiki; +} + +BacklinksIndexer.prototype.init = function() { + this.index = null; +} + +BacklinksIndexer.prototype.rebuild = function() { + this.index = null; +} + +BacklinksIndexer.prototype._getLinks = function(tiddler) { + var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {}); + if(parser) { + return this.wiki.extractLinks(parser.tree); + } + return []; +} + +BacklinksIndexer.prototype.update = function(updateDescriptor) { + if(!this.index) { + return; + } + var newLinks = [], + oldLinks = [], + self = this; + if(updateDescriptor.old.exists) { + oldLinks = this._getLinks(updateDescriptor.old.tiddler); + } + if(updateDescriptor.new.exists) { + newLinks = this._getLinks(updateDescriptor.new.tiddler); + } + + $tw.utils.each(oldLinks,function(link) { + if(self.index[link]) { + delete self.index[link][updateDescriptor.old.tiddler.fields.title]; + } + }); + $tw.utils.each(newLinks,function(link) { + if(!self.index[link]) { + self.index[link] = Object.create(null); + } + self.index[link][updateDescriptor.new.tiddler.fields.title] = true; + }); +} + +BacklinksIndexer.prototype.lookup = function(title) { + if(!this.index) { + this.index = Object.create(null); + var self = this; + this.wiki.forEachTiddler(function(title,tiddler) { + var links = self._getLinks(tiddler); + $tw.utils.each(links, function(link) { + if(!self.index[link]) { + self.index[link] = Object.create(null); + } + self.index[link][title] = true; + }); + }); + } + if(this.index[title]) { + return Object.keys(this.index[title]); + } else { + return []; + } +} + +exports.BacklinksIndexer = BacklinksIndexer; + +})(); diff --git a/core/modules/wiki.js b/core/modules/wiki.js index fc8b42eda..d44940cb6 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -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