Bug 1523602 - Re-use existing rows when receiving results. r=mak

Differential Revision: https://phabricator.services.mozilla.com/D25047

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dão Gottwald 2019-03-28 12:59:57 +00:00
Родитель 11ed6b29f2
Коммит a31fab267c
2 изменённых файлов: 90 добавлений и 76 удалений

Просмотреть файл

@ -204,16 +204,26 @@ class UrlbarView {
onQueryResults(queryContext) { onQueryResults(queryContext) {
this._queryContext = queryContext; this._queryContext = queryContext;
let fragment = this.document.createDocumentFragment(); let resultIndex = 0;
for (let resultIndex in queryContext.results) { for (let row of this._rows.children) {
fragment.appendChild(this._createRow(resultIndex)); if (resultIndex < queryContext.results.length) {
this._updateRow(row, resultIndex);
} else {
row.remove();
}
resultIndex++;
}
for (; resultIndex < queryContext.results.length; resultIndex++) {
let row = this._createRow();
this._updateRow(row, resultIndex);
this._rows.appendChild(row);
} }
let isFirstPreselectedResult = false; let isFirstPreselectedResult = false;
if (queryContext.lastResultCount == 0) { if (queryContext.lastResultCount == 0) {
if (queryContext.preselected) { if (queryContext.preselected) {
isFirstPreselectedResult = true; isFirstPreselectedResult = true;
this._selectItem(fragment.firstElementChild, { this._selectItem(this._rows.firstElementChild, {
updateInput: false, updateInput: false,
setAccessibleFocus: false, setAccessibleFocus: false,
}); });
@ -230,22 +240,8 @@ class UrlbarView {
(trimmedValue[0] != UrlbarTokenizer.RESTRICT.SEARCH || (trimmedValue[0] != UrlbarTokenizer.RESTRICT.SEARCH ||
trimmedValue.length != 1)) trimmedValue.length != 1))
); );
} else if (this._selected) {
// Ensure the selection is stable.
// TODO bug 1523602: the selection should stay on the node that had it, if
// it's still in the current result set.
let resultIndex = this._selected.getAttribute("resultIndex");
this._selectItem(fragment.children[resultIndex], {
updateInput: false,
setAccessibleFocus: false,
});
} }
// TODO bug 1523602: For now, clear the results for each set received.
// We should be updating the existing list instead.
this._rows.textContent = "";
this._rows.appendChild(fragment);
this._openPanel(); this._openPanel();
if (isFirstPreselectedResult) { if (isFirstPreselectedResult) {
@ -394,24 +390,11 @@ class UrlbarView {
this.panel.style.setProperty("--item-content-width", Math.round(contentWidth) + "px"); this.panel.style.setProperty("--item-content-width", Math.round(contentWidth) + "px");
} }
_createRow(resultIndex) { _createRow() {
let result = this._queryContext.results[resultIndex];
let item = this._createElement("div"); let item = this._createElement("div");
item.id = "urlbarView-row-" + resultIndex;
item.className = "urlbarView-row"; item.className = "urlbarView-row";
item.setAttribute("resultIndex", resultIndex);
item.setAttribute("role", "option"); item.setAttribute("role", "option");
item._elements = new Map;
if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH &&
!result.payload.isKeywordOffer) {
item.setAttribute("type", "search");
} else if (result.type == UrlbarUtils.RESULT_TYPE.REMOTE_TAB) {
item.setAttribute("type", "remotetab");
} else if (result.type == UrlbarUtils.RESULT_TYPE.TAB_SWITCH) {
item.setAttribute("type", "switchtab");
} else if (result.source == UrlbarUtils.RESULT_SOURCE.BOOKMARKS) {
item.setAttribute("type", "bookmark");
}
let content = this._createElement("span"); let content = this._createElement("span");
content.className = "urlbarView-row-inner"; content.className = "urlbarView-row-inner";
@ -423,23 +406,67 @@ class UrlbarView {
let favicon = this._createElement("img"); let favicon = this._createElement("img");
favicon.className = "urlbarView-favicon"; favicon.className = "urlbarView-favicon";
content.appendChild(favicon);
item._elements.set("favicon", favicon);
let title = this._createElement("span");
title.className = "urlbarView-title";
content.appendChild(title);
item._elements.set("title", title);
let tagsContainer = this._createElement("div");
tagsContainer.className = "urlbarView-tags";
content.appendChild(tagsContainer);
item._elements.set("tagsContainer", tagsContainer);
let titleSeparator = this._createElement("span");
titleSeparator.className = "urlbarView-title-separator";
content.appendChild(titleSeparator);
let action = this._createElement("span");
action.className = "urlbarView-secondary urlbarView-action";
content.appendChild(action);
item._elements.set("action", action);
let url = this._createElement("span");
url.className = "urlbarView-secondary urlbarView-url";
content.appendChild(url);
item._elements.set("url", url);
return item;
}
_updateRow(item, resultIndex) {
let result = this._queryContext.results[resultIndex];
item.id = "urlbarView-row-" + resultIndex;
item.setAttribute("resultIndex", resultIndex);
if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH &&
!result.payload.isKeywordOffer) {
item.setAttribute("type", "search");
} else if (result.type == UrlbarUtils.RESULT_TYPE.REMOTE_TAB) {
item.setAttribute("type", "remotetab");
} else if (result.type == UrlbarUtils.RESULT_TYPE.TAB_SWITCH) {
item.setAttribute("type", "switchtab");
} else if (result.source == UrlbarUtils.RESULT_SOURCE.BOOKMARKS) {
item.setAttribute("type", "bookmark");
} else {
item.removeAttribute("type");
}
let favicon = item._elements.get("favicon");
if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH || if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH ||
result.type == UrlbarUtils.RESULT_TYPE.KEYWORD) { result.type == UrlbarUtils.RESULT_TYPE.KEYWORD) {
favicon.src = result.payload.icon || UrlbarUtils.ICON.SEARCH_GLASS; favicon.src = result.payload.icon || UrlbarUtils.ICON.SEARCH_GLASS;
} else { } else {
favicon.src = result.payload.icon || UrlbarUtils.ICON.DEFAULT; favicon.src = result.payload.icon || UrlbarUtils.ICON.DEFAULT;
} }
content.appendChild(favicon);
let title = this._createElement("span");
title.className = "urlbarView-title";
this._addTextContentWithHighlights( this._addTextContentWithHighlights(
title, result.title, result.titleHighlights); item._elements.get("title"), result.title, result.titleHighlights);
content.appendChild(title);
let tagsContainer = item._elements.get("tagsContainer");
if (result.payload.tags && result.payload.tags.length > 0) { if (result.payload.tags && result.payload.tags.length > 0) {
const tagsContainer = this._createElement("div");
tagsContainer.className = "urlbarView-tags";
tagsContainer.append(...result.payload.tags.map((tag, i) => { tagsContainer.append(...result.payload.tags.map((tag, i) => {
const element = this._createElement("span"); const element = this._createElement("span");
element.className = "urlbarView-tag"; element.className = "urlbarView-tag";
@ -447,63 +474,49 @@ class UrlbarView {
element, tag, result.payloadHighlights.tags[i]); element, tag, result.payloadHighlights.tags[i]);
return element; return element;
})); }));
content.appendChild(tagsContainer); } else {
tagsContainer.textContent = "";
} }
let titleSeparator = this._createElement("span"); let action = "";
titleSeparator.className = "urlbarView-title-separator"; let setURL = false;
content.appendChild(titleSeparator);
let action;
let url;
let setAction = text => {
action = this._createElement("span");
action.className = "urlbarView-secondary urlbarView-action";
action.textContent = text;
};
let setURL = () => {
url = this._createElement("span");
url.className = "urlbarView-secondary urlbarView-url";
this._addTextContentWithHighlights(url, result.payload.displayUrl,
result.payloadHighlights.displayUrl || []);
};
switch (result.type) { switch (result.type) {
case UrlbarUtils.RESULT_TYPE.TAB_SWITCH: case UrlbarUtils.RESULT_TYPE.TAB_SWITCH:
setAction(bundle.GetStringFromName("switchToTab2")); action = bundle.GetStringFromName("switchToTab2");
setURL(); setURL = true;
break; break;
case UrlbarUtils.RESULT_TYPE.REMOTE_TAB: case UrlbarUtils.RESULT_TYPE.REMOTE_TAB:
setAction(result.payload.device); action = result.payload.device;
setURL(); setURL = true;
break; break;
case UrlbarUtils.RESULT_TYPE.SEARCH: case UrlbarUtils.RESULT_TYPE.SEARCH:
setAction(bundle.formatStringFromName("searchWithEngine", action = bundle.formatStringFromName("searchWithEngine",
[result.payload.engine], 1)); [result.payload.engine], 1);
break; break;
case UrlbarUtils.RESULT_TYPE.KEYWORD: case UrlbarUtils.RESULT_TYPE.KEYWORD:
if (result.payload.input.trim() == result.payload.keyword) { if (result.payload.input.trim() == result.payload.keyword) {
setAction(bundle.GetStringFromName("visit")); action = bundle.GetStringFromName("visit");
} }
break; break;
case UrlbarUtils.RESULT_TYPE.OMNIBOX: case UrlbarUtils.RESULT_TYPE.OMNIBOX:
setAction(result.payload.content); action = result.payload.content;
break; break;
default: default:
if (result.heuristic) { if (result.heuristic) {
setAction(bundle.GetStringFromName("visit")); action = bundle.GetStringFromName("visit");
} else { } else {
setURL(); setURL = true;
} }
break; break;
} }
if (action) { let url = item._elements.get("url");
content.appendChild(action); if (setURL) {
this._addTextContentWithHighlights(url, result.payload.displayUrl,
result.payloadHighlights.displayUrl || []);
} else {
url.textContent = "";
} }
if (url) { item._elements.get("action").textContent = action;
content.appendChild(url);
}
return item;
} }
_selectItem(item, { _selectItem(item, {
@ -551,6 +564,7 @@ class UrlbarView {
* The matches to highlight in the text. * The matches to highlight in the text.
*/ */
_addTextContentWithHighlights(parentNode, textContent, highlights) { _addTextContentWithHighlights(parentNode, textContent, highlights) {
parentNode.textContent = "";
if (!textContent) { if (!textContent) {
return; return;
} }

Просмотреть файл

@ -126,7 +126,7 @@
margin: 0 .4em; margin: 0 .4em;
} }
.urlbarView-title:empty + .urlbarView-title-separator { .urlbarView-title:empty + .urlbarView-tags:empty + .urlbarView-title-separator {
display: none; display: none;
} }