1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-11-17 07:47:24 +00:00

Fix issues with ordering of tagged items (#3301)

* Added better handling for sortByList manual placements

If manual placement specifications show up in an inconvenient order,
sortByList, will go to the trouble of processing them in that order.

* Added tests to confirm solution to (#3296)

...That custom tag ordering will not choke when tiddlers get sorted after their dependencies have been placed around them

* Corrected list-after bug when referencing external titles

* Using more error-proof $tw.utils.hop in sortByList

* minor indentation correction in test-tags.js
This commit is contained in:
Cameron Fischer
2018-10-07 07:15:33 -04:00
committed by Jeremy Ruston
parent 5dcdff4b37
commit d8007386cf
2 changed files with 92 additions and 29 deletions

View File

@@ -558,39 +558,49 @@ exports.sortByList = function(array,listTitle) {
} }
} }
// Finally obey the list-before and list-after fields of each tiddler in turn // Finally obey the list-before and list-after fields of each tiddler in turn
var sortedTitles = titles.slice(0); var sortedTitles = titles.slice(0),
for(t=0; t<sortedTitles.length; t++) { replacedTitles = Object.create(null),
title = sortedTitles[t]; self = this;
var currPos = titles.indexOf(title), function replaceItem(title) {
newPos = -1, if(!$tw.utils.hop(replacedTitles, title)) {
tiddler = this.getTiddler(title); replacedTitles[title] = true;
if(tiddler) { var newPos = -1,
var beforeTitle = tiddler.fields["list-before"], tiddler = self.getTiddler(title);
afterTitle = tiddler.fields["list-after"]; if(tiddler) {
if(beforeTitle === "") { var beforeTitle = tiddler.fields["list-before"],
newPos = 0; afterTitle = tiddler.fields["list-after"];
} else if(afterTitle === "") { if(beforeTitle === "") {
newPos = titles.length; newPos = 0;
} else if(beforeTitle) { } else if(afterTitle === "") {
newPos = titles.indexOf(beforeTitle); newPos = titles.length;
} else if(afterTitle) { } else if(beforeTitle) {
newPos = titles.indexOf(afterTitle); replaceItem(beforeTitle);
if(newPos >= 0) { newPos = titles.indexOf(beforeTitle);
++newPos; } else if(afterTitle) {
replaceItem(afterTitle);
newPos = titles.indexOf(afterTitle);
if(newPos >= 0) {
++newPos;
}
} }
} // We get the currPos //after// figuring out the newPos, because recursive replaceItem calls might alter title's currPos
if(newPos === -1) { var currPos = titles.indexOf(title);
newPos = currPos; if(newPos === -1) {
} newPos = currPos;
if(newPos !== currPos) { }
titles.splice(currPos,1); if(currPos >= 0 && newPos !== currPos) {
if(newPos >= currPos) { titles.splice(currPos,1);
newPos--; if(newPos >= currPos) {
newPos--;
}
titles.splice(newPos,0,title);
} }
titles.splice(newPos,0,title);
} }
} }
};
for(t=0; t<sortedTitles.length; t++) {
title = sortedTitles[t];
replaceItem(title);
} }
return titles; return titles;
} }

View File

@@ -86,6 +86,59 @@ describe("Tag tests", function() {
expect(wiki.filterTiddlers("[tag[TiddlerSeventh]]").join(",")).toBe("Tiddler10,TiddlerOne,Tiddler Three,Tiddler11,Tiddler9,a fourth tiddler"); expect(wiki.filterTiddlers("[tag[TiddlerSeventh]]").join(",")).toBe("Tiddler10,TiddlerOne,Tiddler Three,Tiddler11,Tiddler9,a fourth tiddler");
}); });
// Tests for issue (#3296)
it("should apply tag ordering in order of dependency", function () {
var wiki = new $tw.Wiki();
wiki.addTiddler({ title: "A", text: "", tags: "sortTag", "list-after": "B"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag", "list-after": "C"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("C,B,A");
});
it("should handle self-referencing dependency without looping infinitely", function() {
var wiki = new $tw.Wiki();
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag", "list-after": "B"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
});
it("should handle empty list-after ordering", function() {
var wiki = new $tw.Wiki();
wiki.addTiddler({ title: "A", text: "", tags: "sortTag", "list-after": ""});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("B,C,A");
});
// If a tiddler in the tag references a tiddler OUTSIDE of the tag
// with list-after/before, we need to make sure we don't accidentally
// handle that external tiddler, or that reference.
it("should gracefully handle dependencies that aren't in the tag list", function() {
var wiki = new $tw.Wiki();
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag", "list-after": "Z"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "Z", text: "", tags: "EXCLUDED", "list-before": ""});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
});
it("should handle javascript-specific titles", function() {
var wiki = new $tw.Wiki();
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "__proto__", text: "", tags: "sortTag", "list-before": ""});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("__proto__,A");
});
}); });
})(); })();