Fx60: Mostly fix autocomplete

There's still a bug when autocompleting tags where the value remains in
the new text field.
This commit is contained in:
Dan Stillman 2019-10-24 04:45:45 -04:00
parent 0aa351cb8d
commit ba15c2b53e
3 changed files with 53 additions and 37 deletions

View file

@ -1615,25 +1615,23 @@
<parameter name="textbox"/> <parameter name="textbox"/>
<parameter name="stayFocused"/> <parameter name="stayFocused"/>
<body><![CDATA[ <body><![CDATA[
var comment = false;
var controller = textbox.controller; var controller = textbox.controller;
if (!controller.matchCount) return; if (!controller.matchCount) return;
for (var i=0; i<controller.matchCount; i++) var id = false;
{ for (let i = 0; i < controller.matchCount; i++) {
if (controller.getValueAt(i) == textbox.value) if (controller.getCommentAt(i) == textbox.value) {
{ id = controller.getLabelAt(i);
comment = controller.getCommentAt(i);
break; break;
} }
} }
// No result selected // No result selected
if (!comment) { if (!id) {
return; return;
} }
var [creatorID, numFields] = comment.split('-'); var [creatorID, numFields] = id.split('-');
// If result uses two fields, save both // If result uses two fields, save both
if (numFields==2) if (numFields==2)

View file

@ -758,6 +758,24 @@
font-size: 22px; font-size: 22px;
} }
/* Missing in Fx60 */
.autocomplete-richlistbox {
border: 1px solid transparent;
min-height: 1.8em;
}
.autocomplete-richlistitem {
font: message-box;
padding: 1px;
height: 1.5em;
min-height: 1.5em;
}
.autocomplete-richlistitem[selected] {
background-color: Highlight;
color: HighlightText;
}
/* BEGIN 2X BLOCK -- DO NOT EDIT MANUALLY -- USE 2XIZE */ /* BEGIN 2X BLOCK -- DO NOT EDIT MANUALLY -- USE 2XIZE */
@media (min-resolution: 1.25dppx) { @media (min-resolution: 1.25dppx) {

View file

@ -71,7 +71,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
break; break;
case 'tag': case 'tag':
var sql = "SELECT DISTINCT name AS val, NULL AS comment FROM tags WHERE name LIKE ? ESCAPE '\\'"; var sql = "SELECT DISTINCT name AS val, NULL AS id FROM tags WHERE name LIKE ? ESCAPE '\\'";
var sqlParams = [Zotero.DB.escapeSQLExpression(searchString) + '%']; var sqlParams = [Zotero.DB.escapeSQLExpression(searchString) + '%'];
if (searchParams.libraryID !== undefined) { if (searchParams.libraryID !== undefined) {
sql += " AND tagID IN (SELECT tagID FROM itemTags JOIN items USING (itemID) " sql += " AND tagID IN (SELECT tagID FROM itemTags JOIN items USING (itemID) "
@ -93,7 +93,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
// 2 == search both // 2 == search both
if (searchParams.fieldMode == 2) { if (searchParams.fieldMode == 2) {
var sql = "SELECT DISTINCT CASE fieldMode WHEN 1 THEN lastName " var sql = "SELECT DISTINCT CASE fieldMode WHEN 1 THEN lastName "
+ "WHEN 0 THEN firstName || ' ' || lastName END AS val, NULL AS comment " + "WHEN 0 THEN firstName || ' ' || lastName END AS val, NULL AS id "
+ "FROM creators "; + "FROM creators ";
if (searchParams.libraryID !== undefined) { if (searchParams.libraryID !== undefined) {
sql += "JOIN itemCreators USING (creatorID) JOIN items USING (itemID) "; sql += "JOIN itemCreators USING (creatorID) JOIN items USING (itemID) ";
@ -112,7 +112,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
{ {
var sql = "SELECT DISTINCT "; var sql = "SELECT DISTINCT ";
if (searchParams.fieldMode == 1) { if (searchParams.fieldMode == 1) {
sql += "lastName AS val, creatorID || '-1' AS comment"; sql += "lastName AS val, creatorID || '-1' AS id";
} }
// Retrieve the matches in the specified field // Retrieve the matches in the specified field
// as well as any full names using the name // as well as any full names using the name
@ -127,7 +127,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
+ "ELSE lastName || ', ' || firstName END AS val, " + "ELSE lastName || ', ' || firstName END AS val, "
+ "creatorID || '-' || CASE " + "creatorID || '-' || CASE "
+ "WHEN (firstName = '' OR firstName IS NULL) THEN 1 " + "WHEN (firstName = '' OR firstName IS NULL) THEN 1 "
+ "ELSE 2 END AS comment"; + "ELSE 2 END AS id";
} }
var fromSQL = " FROM creators " var fromSQL = " FROM creators "
@ -160,7 +160,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
// as well (i.e. "Shakespeare"), and group to collapse repeats // as well (i.e. "Shakespeare"), and group to collapse repeats
if (searchParams.fieldMode != 1) { if (searchParams.fieldMode != 1) {
sql = "SELECT * FROM (" + sql + " UNION SELECT DISTINCT " sql = "SELECT * FROM (" + sql + " UNION SELECT DISTINCT "
+ subField + " AS val, creatorID || '-1' AS comment" + subField + " AS val, creatorID || '-1' AS id"
+ fromSQL + ") GROUP BY val"; + fromSQL + ") GROUP BY val";
sqlParams = sqlParams.concat(sqlParams); sqlParams = sqlParams.concat(sqlParams);
} }
@ -171,7 +171,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
case 'dateModified': case 'dateModified':
case 'dateAdded': case 'dateAdded':
var sql = "SELECT DISTINCT DATE(" + fieldName + ", 'localtime') AS val, NULL AS comment FROM items " var sql = "SELECT DISTINCT DATE(" + fieldName + ", 'localtime') AS val, NULL AS id FROM items "
+ "WHERE " + fieldName + " LIKE ? ORDER BY " + fieldName; + "WHERE " + fieldName + " LIKE ? ORDER BY " + fieldName;
var sqlParams = [searchString + '%']; var sqlParams = [searchString + '%'];
break; break;
@ -179,7 +179,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
case 'accessDate': case 'accessDate':
var fieldID = Zotero.ItemFields.getID('accessDate'); var fieldID = Zotero.ItemFields.getID('accessDate');
var sql = "SELECT DISTINCT DATE(value, 'localtime') AS val, NULL AS comment FROM itemData " var sql = "SELECT DISTINCT DATE(value, 'localtime') AS val, NULL AS id FROM itemData "
+ "WHERE fieldID=? AND value LIKE ? ORDER BY value"; + "WHERE fieldID=? AND value LIKE ? ORDER BY value";
var sqlParams = [fieldID, searchString + '%']; var sqlParams = [fieldID, searchString + '%'];
break; break;
@ -197,7 +197,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
// use the user part of the multipart field // use the user part of the multipart field
var valueField = fieldName == 'date' ? 'SUBSTR(value, 12, 100)' : 'value'; var valueField = fieldName == 'date' ? 'SUBSTR(value, 12, 100)' : 'value';
var sql = "SELECT DISTINCT " + valueField + " AS val, NULL AS comment " var sql = "SELECT DISTINCT " + valueField + " AS val, NULL AS id "
+ "FROM itemData NATURAL JOIN itemDataValues " + "FROM itemData NATURAL JOIN itemDataValues "
+ "WHERE fieldID=?1 AND " + valueField + "WHERE fieldID=?1 AND " + valueField
+ " LIKE ?2 " + " LIKE ?2 "
@ -220,9 +220,9 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
cancel(); cancel();
return; return;
} }
var result = row.getResultByIndex(0); var value = row.getResultByIndex(0);
var comment = row.getResultByIndex(1); var id = row.getResultByIndex(1);
this.updateResult(result, comment, true); this.updateResult(value, id);
}.bind(this); }.bind(this);
} }
var resultCode; var resultCode;
@ -233,7 +233,7 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
resultsCallback(results); resultsCallback(results);
this.updateResults( this.updateResults(
Object.values(results).map(x => x.val), Object.values(results).map(x => x.val),
Object.values(results).map(x => x.comment), Object.values(results).map(x => x.id),
false false
); );
} }
@ -251,36 +251,36 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
}); });
ZoteroAutoComplete.prototype.updateResult = function (result, comment) { ZoteroAutoComplete.prototype.updateResult = function (value, id) {
Zotero.debug("Appending autocomplete value '" + result + "'" + (comment ? " (" + comment + ")" : "")); Zotero.debug(`Appending autocomplete value '${value}'` + (id ? " (" + id + ")" : ''));
// Add to nsIAutoCompleteResult // Add to nsIAutoCompleteResult
this._result.appendMatch(result, comment ? comment : null); this._result.appendMatch(value, value, null, null, null, id);
// Add to our own list // Add to our own list
this._results.push(result); this._results.push(value);
// Only update the UI every 10 records // Only update the UI every 10 records
if (this._result.matchCount % 10 == 0) { if (this._result.matchCount % 10 == 0) {
this._result.setSearchResult(Ci.nsIAutoCompleteResult.RESULT_SUCCESS_ONGOING); this._result.setSearchResult(Ci.nsIAutoCompleteResult.RESULT_SUCCESS_ONGOING);
this._listener.onUpdateSearchResult(this, this._result); this._listener.onSearchResult(this, this._result);
} }
} }
ZoteroAutoComplete.prototype.updateResults = function (results, comments, ongoing, resultCode) { ZoteroAutoComplete.prototype.updateResults = function (values, ids, ongoing, resultCode) {
if (!results) { if (!values) {
results = []; values = [];
} }
if (!comments) { if (!ids) {
comments = []; ids = [];
} }
for (var i=0; i<results.length; i++) { for (let i = 0; i < values.length; i++) {
let result = results[i]; let value = values[i];
if (this._results.indexOf(result) == -1) { if (!this._results.includes(value)) {
comment = comments[i] ? comments[i] : null; let id = ids[i] || null;
Zotero.debug("Adding autocomplete value '" + result + "'" + (comment ? " (" + comment + ")" : "")); Zotero.debug("Adding autocomplete value '" + value + "'" + (id ? " (" + id + ")" : ""));
this._result.appendMatch(result, comment, null, null); this._result.appendMatch(value, value, null, null, null, id);
this._results.push(result); this._results.push(value);
} }
else { else {
//Zotero.debug("Skipping existing value '" + result + "'"); //Zotero.debug("Skipping existing value '" + result + "'");