1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-12-28 02:50:27 +00:00

Fix search method for search tokens spread across fields (#3641)

* Fix search method for search tokens spread across fields

Addresses GH #3636, which reports that if you're searching for "test
body", and "test" only appears in the title field, and "body" only appears
in the text field, 5.1.18's search method won't yield that tiddler as a
result, which appears to be a regression from the 5.1.17 behavior

* Add test for searching for multiple tokens across fields

Verifies GH #3636:

> If I create a tiddler in the empty edition with the title "Test tiddler" and content "Body content", searching the wiki for "test body" yields no results under either "title matches" or "all matches". Searching for either word individually turns up "Test tiddler", and repeating this in an empty wiki I created from the 5.1.17 tag causes "Test tiddler" to show up under "all matches".
This commit is contained in:
Rob Hoelz 2018-12-17 05:19:48 -06:00 committed by Jeremy Ruston
parent d5618ca60a
commit d8b291bc04
2 changed files with 20 additions and 24 deletions

View File

@ -1119,6 +1119,8 @@ exports.search = function(text,options) {
if(!searchTermsRegExps) {
return true;
}
var notYetFound = searchTermsRegExps.slice();
var tiddler = self.getTiddler(title);
if(!tiddler) {
tiddler = new $tw.Tiddler({title: title, text: "", type: "text/vnd.tiddlywiki"});
@ -1137,50 +1139,40 @@ exports.search = function(text,options) {
} else {
searchFields = fields;
}
for(var fieldIndex=0; fieldIndex<searchFields.length; fieldIndex++) {
for(var fieldIndex=0; notYetFound.length>0 && fieldIndex<searchFields.length; fieldIndex++) {
// Don't search the text field if the content type is binary
var fieldName = searchFields[fieldIndex];
if(fieldName === "text" && contentTypeInfo.encoding !== "utf8") {
break;
}
var matches = true,
str = tiddler.fields[fieldName],
var str = tiddler.fields[fieldName],
t;
if(str) {
if($tw.utils.isArray(str)) {
// If the field value is an array, test each regexp against each field array entry and fail if each regexp doesn't match at least one field array entry
for(t=0; t<searchTermsRegExps.length; t++) {
var thisRegExpMatches = false
for(var s=0; s<str.length; s++) {
if(searchTermsRegExps[t].test(str[s])) {
thisRegExpMatches = true;
break;
for(var s=0; s<str.length; s++) {
for(t=0; t<notYetFound.length;) {
if(notYetFound[t].test(str[s])) {
notYetFound.splice(t, 1);
} else {
t++;
}
}
// Bail if the current search expression doesn't match any entry in the current field array
if(!thisRegExpMatches) {
matches = false;
break;
}
}
} else {
// If the field isn't an array, force it to a string and test each regexp against it and fail if any do not match
str = tiddler.getFieldString(fieldName);
for(t=0; t<searchTermsRegExps.length; t++) {
if(!searchTermsRegExps[t].test(str)) {
matches = false;
break;
for(t=0; t<notYetFound.length;) {
if(notYetFound[t].test(str)) {
notYetFound.splice(t, 1);
} else {
t++;
}
}
}
} else {
matches = false;
}
if(matches) {
return true;
}
};
return false;
return notYetFound.length == 0;
};
// Loop through all the tiddlers doing the search
var results = [],

View File

@ -264,6 +264,10 @@ describe("Filter tests", function() {
expect(wiki.filterTiddlers("[search:*:[g]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
});
it("should yield search results that have search tokens spread across different fields", function() {
expect(wiki.filterTiddlers("[search[fox one]sort[title]]").join(",")).toBe("TiddlerOne");
});
it("should handle the each operator", function() {
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/TiddlerTwo,TiddlerOne");
expect(wiki.filterTiddlers("[each:list-item[tags]sort[title]]").join(",")).toBe("one,two");