Bug 1022228 - Improve the UI of the search result tab and improve links discoverability. r=mkmelin,ui-r=paenglab
authorAlessandro Castellani <alessandro@thunderbird.net>
Fri, 07 Feb 2020 17:13:58 -0800
changeset 37259 7dc97f6d28a347bee552760e270dbdb254b03e7a
parent 37258 6ff16e8c98c712ff3954da1707e5698b88f0114b
child 37260 9185bf0f28e29d56ad0c2fc5cb167b2ef000669d
push id2552
push userclokep@gmail.com
push dateMon, 10 Feb 2020 21:24:16 +0000
treeherdercomm-beta@f95a6f4408a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, paenglab
bugs1022228
Bug 1022228 - Improve the UI of the search result tab and improve links discoverability. r=mkmelin,ui-r=paenglab
mail/base/content/glodaFacet.js
mail/base/content/glodaFacetView.css
mail/base/content/glodaFacetView.js
mail/base/content/glodaFacetView.xhtml
mail/locales/en-US/chrome/messenger/glodaFacetView.dtd
mail/locales/en-US/chrome/messenger/glodaFacetView.properties
mail/themes/linux/mail/glodaFacetView.css
mail/themes/osx/mail/glodaFacetView.css
mail/themes/shared/jar.inc.mn
mail/themes/shared/mail/icons/new-window.svg
mail/themes/shared/mail/icons/popular.svg
mail/themes/windows/mail/glodaFacetView.css
--- a/mail/base/content/glodaFacet.js
+++ b/mail/base/content/glodaFacet.js
@@ -76,55 +76,69 @@
   class MozFacetResultsMessage extends HTMLElement {
     connectedCallback() {
       const header = document.createElement("div");
       header.classList.add("results-message-header");
 
       this.countNode = document.createElement("h2");
       this.countNode.classList.add("results-message-count");
 
-      const showallDiv = document.createElement("div");
-      showallDiv.classList.add("results-message-showall");
+      this.toggleTimeline = document.createElement("label");
+      this.toggleTimeline.setAttribute("id", "date-toggle");
+      this.toggleTimeline.setAttribute("role", "button");
+      this.toggleTimeline.setAttribute("tabindex", 0);
+      this.toggleTimeline.classList.add("gloda-timeline-button");
+      this.toggleTimeline.addEventListener("click", () => {
+        FacetContext.toggleTimeline();
+      });
+      this.toggleTimeline.addEventListener("keypress", event => {
+        if (event.charCode == KeyEvent.DOM_VK_SPACE) {
+          FacetContext.toggleTimeline();
+          event.preventDefault();
+        }
+      });
 
-      this.showNode = document.createElement("span");
-      this.showNode.classList.add("results-message-showall-button");
-      this.showNode.setAttribute("tabindex", "0");
-      this.showNode.setAttribute("role", "button");
-      this.showNode.onclick = () => {
-        FacetContext.showActiveSetInTab();
-      };
+      const timelineImage = document.createElement("img");
+      timelineImage.setAttribute(
+        "src",
+        "chrome://messenger/skin/icons/popular.svg"
+      );
+      this.toggleTimeline.appendChild(timelineImage);
+
+      this.toggleText = document.createElement("span");
+      this.toggleTimeline.appendChild(this.toggleText);
 
       const sortDiv = document.createElement("div");
       sortDiv.classList.add("results-message-sort-bar");
 
-      this.sortLabelNode = document.createElement("span");
-      this.sortLabelNode.classList.add("result-message-sort-label");
+      this.sortSelect = document.createElement("select");
 
-      this.sortRelevanceNode = document.createElement("span");
-      this.sortRelevanceNode.classList.add("results-message-sort-value");
-      this.sortRelevanceNode.setAttribute("tabindex", "0");
-      this.sortRelevanceNode.setAttribute("role", "button");
+      let revelanceItem = document.createElement("option");
+      revelanceItem.textContent = glodaFacetStrings.get(
+        "glodaFacetView.results.message.sort.relevance2"
+      );
+      revelanceItem.setAttribute("value", "-dascore");
+      revelanceItem.setAttribute("selected", true);
+      this.sortSelect.appendChild(revelanceItem);
 
-      this.sortDateNode = document.createElement("span");
-      this.sortDateNode.classList.add("results-message-sort-value");
-      this.sortDateNode.setAttribute("tabindex", "0");
-      this.sortDateNode.setAttribute("role", "button");
+      let dateItem = document.createElement("option");
+      dateItem.textContent = glodaFacetStrings.get(
+        "glodaFacetView.results.message.sort.date2"
+      );
+      dateItem.setAttribute("value", "-date");
+      this.sortSelect.appendChild(dateItem);
 
       this.messagesNode = document.createElement("div");
       this.messagesNode.classList.add("messages");
 
       header.appendChild(this.countNode);
-      header.appendChild(showallDiv);
+      header.appendChild(this.toggleTimeline);
       header.appendChild(sortDiv);
 
-      showallDiv.appendChild(this.showNode);
-
-      sortDiv.appendChild(this.sortLabelNode);
-      sortDiv.appendChild(this.sortRelevanceNode);
-      sortDiv.appendChild(this.sortDateNode);
+      sortDiv.appendChild(this.sortSelect);
 
       this.appendChild(header);
       this.appendChild(this.messagesNode);
     }
 
     setMessages(messages) {
       let topMessagesPluralFormat = glodaFacetStrings.get(
         "glodaFacetView.results.header.countLabel.NMessages"
@@ -150,103 +164,39 @@
         "#1",
         totalCount.toLocaleString()
       );
 
       this.countNode.textContent = groupingFormat
         .replace("#1", topMessagesStr)
         .replace("#2", outOfStr);
 
-      const GlodaMessage = Gloda.lookupNounDef("message").clazz;
-      let visible = messages.some(m => m instanceof GlodaMessage);
-      this.showNode.style.display = visible ? "inline" : "none";
-      this.showNode.textContent = glodaFacetStrings.get(
-        "glodaFacetView.results.message.openEmailAsList.label"
-      );
-      this.showNode.setAttribute(
-        "title",
-        glodaFacetStrings.get(
-          "glodaFacetView.results.message.openEmailAsList.tooltip"
-        )
-      );
-      this.showNode.onkeypress = event => {
-        if (event.charCode == KeyEvent.DOM_VK_SPACE) {
-          FacetContext.showActiveSetInTab();
-          event.preventDefault();
-        }
-      };
-
-      this.sortLabelNode.textContent = glodaFacetStrings.get(
-        "glodaFacetView.results.message.sort.label"
-      );
-
-      this.sortRelevanceNode.textContent = glodaFacetStrings.get(
-        "glodaFacetView.results.message.sort.relevance"
+      this.toggleText.textContent = glodaFacetStrings.get(
+        "glodaFacetView.results.message.timeline.label"
       );
 
-      this.sortRelevanceNode.onclick = () => {
-        FacetContext.sortBy = "-dascore";
-        this.updateSortLabels();
-      };
-      this.sortRelevanceNode.onkeypress = event => {
-        if (event.charCode == KeyEvent.DOM_VK_SPACE) {
-          FacetContext.sortBy = "-dascore";
-          this.updateSortLabels();
-          event.preventDefault();
-        }
-      };
-
-      this.sortDateNode.textContent = glodaFacetStrings.get(
-        "glodaFacetView.results.message.sort.date"
-      );
-      this.sortDateNode.onclick = () => {
-        FacetContext.sortBy = "-date";
-        this.updateSortLabels();
-      };
-      this.sortDateNode.onkeypress = event => {
-        if (event.charCode == KeyEvent.DOM_VK_SPACE) {
-          FacetContext.sortBy = "-date";
-          this.updateSortLabels();
-          event.preventDefault();
-        }
-      };
-
-      this.updateSortLabels(FacetContext.sortBy);
+      this.sortSelect.addEventListener("change", () => {
+        FacetContext.sortBy = this.sortSelect.value;
+      });
 
       while (this.messagesNode.hasChildNodes()) {
         this.messagesNode.lastChild.remove();
       }
       try {
         // -- Messages
         for (let message of messages) {
           let msgNode = document.createElement("facet-result-message");
           msgNode.message = message;
           msgNode.setAttribute("class", "message");
           this.messagesNode.appendChild(msgNode);
         }
       } catch (e) {
         logException(e);
       }
     }
-
-    updateSortLabels() {
-      try {
-        let sortBy = FacetContext.sortBy;
-
-        if (sortBy == "-dascore") {
-          this.sortRelevanceNode.setAttribute("selected", "true");
-          this.sortDateNode.removeAttribute("selected");
-        } else if (sortBy == "-date") {
-          this.sortRelevanceNode.removeAttribute("selected");
-          this.sortDateNode.setAttribute("selected", "true");
-        }
-      } catch (e) {
-        logException(e);
-      }
-    }
   }
 
   customElements.define("facet-date", MozFacetDate);
   customElements.define("facet-results-message", MozFacetResultsMessage);
 
   class MozFacetBoolean extends HTMLElement {
     constructor() {
       super();
@@ -282,17 +232,17 @@
         this.build(true);
       }
     }
 
     addChildren() {
       this.bubble = document.createElement("span");
       this.bubble.classList.add("facet-checkbox-bubble");
 
-      this.checkbox = document.createXULElement("input");
+      this.checkbox = document.createElement("input");
       this.checkbox.setAttribute("type", "checkbox");
 
       this.labelNode = document.createElement("span");
       this.labelNode.classList.add("facet-checkbox-label");
 
       this.countNode = document.createElement("span");
       this.countNode.classList.add("facet-checkbox-count");
 
--- a/mail/base/content/glodaFacetView.css
+++ b/mail/base/content/glodaFacetView.css
@@ -1,58 +1,53 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-html {
-  height: 100%;
-}
+@import url("chrome://messenger/skin/");
 
-body {
+body,
+html {
+  margin: 0;
   padding: 0;
-  margin: 0;
   height: 100%;
 }
 
-#table {
-  display: table;
-  width: 100%;
-  height: 100%;
-  position: relative;
-}
-
-#table>div {
-  display: table-row;
+#gloda-facet-view {
+  display: flex;
+  background-color: -moz-Field;
+  color: -moz-FieldText;
+  min-height: 100%;
+  align-items: stretch;
 }
 
 .facets-sidebar {
-  display: table-cell;
   width: 20em;
   max-width: 20em;
   padding: 4px;
-  min-height: 100%;
   padding-inline-start: 1em;
-  font-size: 90%;
 }
 
 #main-column {
+  flex: 1;
   padding-inline-start: 1em;
-  display: table-cell;
 }
 
 #header {
-  position: relative;
-  max-width: 40em;
-  display: block;
+  max-width: 60em;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-top: 2em;
 }
 
 #data-column {
   margin-top: 1em;
   margin-inline-end: 1em;
-  max-width: 40em;
+  max-width: 60em;
   display: flex;
   flex-direction: column;
 }
 
 .popup-menu {
   position: absolute;
   display: block;
   z-index: 100;
@@ -95,88 +90,58 @@ body {
 
 .popup-menu[variety="invisible"] {
   display: none;
 }
 
 /* ===== Query Explanation ===== */
 
 #query-explanation {
-  display: block;
-  height: 40px;
-  font-size: 140% !important;
-  padding: 2px;
   padding-inline-start: 0;
-  padding-top: 1em;
-  padding-inline-end: 80px;
+  font-size: small;
+}
+
+.explanation-fulltext-label,
+.explanation-query-label {
+  font-size: medium;
+  font-weight: bold;
 }
 
 .explanation-fulltext-label,
 .explanation-fulltext-term {
   margin: 0 0.1em;
 }
 
 .explanation-fulltext-criteria {
   color: GrayText;
   margin: 0 0.1em;
 }
 
-
-.explanation-query-label {
-  margin-top: 1ex;
-}
-
 .explanation-query-label,
 .explanation-query-involves,
 .explanation-query-tagged {
   margin-inline-end: 0.5ex;
 }
 
 /* ===== Facets ===== */
 
 h1, h2, h3 {
   cursor: default;
 }
 
-#filter-header-label {
-  margin: 0;
-  margin-top: 1em;
-}
-
 .facetious[uninitialized] {
   display: none !important;
 }
 
 .facetious {
   display: list-item; /* take the whole column width */
   list-style: none;
   padding: 2px;
 }
 
-h1 {
-  font-size: medium !important;
-  padding-bottom: 0.5em;
-}
-
-h2 {
-  display: block;
-  margin: 0;
-  font-size: 100%;
-  margin-top: 1em;
-  margin-bottom: 0.5em;
-}
-
-.facet > h3,
-.facet-content > h3 {
-  font-size: 90%;
-  padding-inline-start: 0;
-  margin-top: 0.5em;
-  margin-bottom: 0.5em;
-}
-
 .facet-included-header[state="empty"],
 .facet-excluded-header[state="empty"],
 .facet-remaindered-header[needed="false"] {
   display: none;
 }
 
 .facet-included-header[state="empty"] + .facet-included,
 .facet-excluded-header[state="empty"] + .facet-excluded,
@@ -194,48 +159,37 @@ h2 {
   display: block;
   padding: 0;
   padding-top: 0.5em;
   margin-inline-end: 1em;
   padding-inline-start: 2em;
   padding-bottom: 1em;
 }
 
-#date-toggle {
-  position: absolute;
-  right: 1em;
-  bottom: 0;
-  margin: 5px;
-  font-size: 90%;
-  text-align: end;
-  display: none;
-  width: 46px !important;
-  height: 17px !important;
-  margin-inline-end: 2px;
-  margin-top: 2px;
-  padding: 4px;
-  background-image: url("chrome://messenger/skin/icons/timeline.svg");
-  background-position: center;
-  background-repeat: no-repeat;
-  border-radius: var(--borderRadius);
+.gloda-timeline-button {
+  -moz-appearance: button !important;
+  margin-inline-start: 8px;
   -moz-context-properties: fill;
-  fill: Highlight;
+  fill: currentColor;
 }
 
-html[dir="rtl"] #date-toggle {
-  right: auto;
-  left: 1em;
+.gloda-timeline-button > img {
+  width: 14px;
+  height: 10px;
+  margin-inline-end: 2px;
+  display: inline-block;
 }
 
-#date-toggle:hover {
-  background-color: Highlight;
-  fill: HighlightText;
+.gloda-timeline-button[checked="true"] {
+  background: var(--toolbarbutton-active-background);
+  border-color: var(--toolbarbutton-active-bordercolor);
+  box-shadow: var(--toolbarbutton-active-boxshadow);
+  border-radius: var(--borderRadius);
 }
 
-
 .facet-date-zoom-out {
   position: absolute;
   top: -18px;
   left: 0;
   width: 24px !important;
   height: 24px !important;
   background-position: center center;
   background-repeat: no-repeat;
@@ -281,30 +235,35 @@ html[dir="rtl"] .date-vis-frame {
 }
 
 .facet-checkbox-bubble {
   display: inline-flex;
   padding: 2px;
   padding-inline-end: 6px;
   border-radius: var(--borderRadius);
   cursor: pointer;
-  font-size: 90%;
+}
+
+.facet-checkbox-bubble > input {
+  display: none;
 }
 
 facet-boolean[disabled] {
   opacity: 0.6;
 }
 
 facet-boolean[disabled] > .facet-checkbox-bubble,
 facet-boolean-filtered[disabled] > .facet-checkbox-bubble {
   cursor: default;
 }
 
 facet-boolean:not([disabled]):hover > .facet-checkbox-bubble,
-facet-boolean-filtered:not([disabled]):hover > .facet-checkbox-bubble {
+facet-boolean-filtered:not([disabled]):hover > .facet-checkbox-bubble,
+facet-boolean[checked="true"]:not([disabled]) > .facet-checkbox-bubble,
+facet-boolean-filtered[checked="true"]:not([disabled]) > .facet-checkbox-bubble {
   background-color: Highlight;
   color: HighlightText;
 }
 
 .facet-checkbox-label,
 .facet-checkbox-count {
   margin: 3px;
 }
@@ -340,54 +299,44 @@ facet-boolean-filtered:not([checked]) > 
 }
 
 .facet-more {
   display: none;
   -moz-appearance: button;
   margin: 1px;
   margin-top: 0.5em;
   padding: 0.2em 1em;
-  font-size: 85%;
   cursor: pointer;
 }
 
 .facet-more[needed="true"] {
   display: inline-block;
 }
 
-.bar {
-  display: block;
-}
-
 html[dir="rtl"] .bar-count {
   right: auto;
   left: 3px;
 }
 
 .barry {
   margin: 0;
   padding: 0;
 }
 
 .bar {
-  display: block;
   position: relative;
   cursor: pointer;
-  font-size: 80%;
-}
-
-.bar:hover {
-  background-color: rgba(0, 0, 0, 0.2);
 }
 
 .bar[selected="true"] {
   background-color: Highlight;
   color: HighlightText;
 }
 
+.bar:hover,
 .bar:focus {
   background-color: Highlight;
   outline: none;
 }
 
 .bar-link {
   display: inline-block;
   text-decoration: none;
@@ -401,88 +350,88 @@ html[dir="rtl"] .bar-count {
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
 }
 
 .bar-count {
   position: absolute;
   display: block;
-  right: 3px;
-  margin-inline-end: 1.5em;
+  right: 0;
+  margin-inline-end: 8px;
   line-height: 1.6em;
   color: GrayText;
 }
 
 html[dir="rtl"] .bar-link {
   padding: 0.3em 0.5em 0.3em 2em;
 }
 
-.bar:hover > .bar-link {
-  color: GrayText;
-}
-
+.bar:hover > .bar-link,
+.bar:hover > .bar-count,
+.bar:focus > .bar-link,
 .bar:focus > .bar-count {
   color: HighlightText;
 }
+
 .bar[selected="true"]> .bar-link {
   color: HighlightText;
 }
 .bar[selected="true"] > .bar-count {
   color: HighlightText;
 }
 
 /* ===== Results ===== */
 
 .results-message-header {
   display: none; /* $('.results-message-header').show() is run if there are results */
-  width: 100%;
-  background-color: rgba(0,0,0,0.1);
-  border-top: 2px solid GrayText;
-  padding: 2px;
+  border-bottom: 2px solid rgba(0,0,0,0.1);
+  padding: 4px 2px;
+  padding-inline-end: 0;
   margin-bottom: 0.5em;
 }
 
 #results[state="some"] .results-message-header {
-  display: table;
+  display: flex;
+  align-items: center;
 }
 
 .results-message-count {
-  display: table-cell;
+  font-weight: 600;
+  font-size: 1rem;
   margin: 0;
-  padding-inline-start: 2px;
-  font-weight: normal;
-  font-size: small;
-}
-
-.results-message-showall {
-  display: table-cell;
 }
 
 .results-message-showall-button {
-  padding: 0.2em 1em;
-  font-size: small;
+  -moz-appearance: none !important;
+  color: -moz-NativehyperlinkText;
+  cursor: pointer;
+  padding: 4px;
   border-radius: var(--borderRadius);
-  cursor: pointer;
-  text-align: center;
+  padding-inline-end: 20px;
+  margin-inline-end: 2px;
+  -moz-context-properties: fill;
+  fill: currentColor;
+  background-image: url("chrome://messenger/skin/icons/new-window.svg");
+  background-position: right 4px center;
+  background-size: 11px;
+  background-repeat: no-repeat;
+  transition: all ease 140ms;
 }
 
 .results-message-showall-button:hover,
 .results-message-showall-button:focus {
-  background-color: var(--buttonHoverColor);
-  color: var(--buttonHoverTextColor);
-  text-decoration: none;
+  background-color: Highlight;
+  color: Highlighttext;
 }
 
-
 .results-message-sort-bar {
-  display: table-cell;
-  padding-inline-end: 2px;
-  text-align: end;
-  font-size: small;
+  flex: 1;
+  display: flex;
+  justify-content: end;
 }
 
 .results-message-sort-label {
   color: grey;
 }
 
 .results-message-sort-value {
   border-radius: var(--borderRadius);
--- a/mail/base/content/glodaFacetView.js
+++ b/mail/base/content/glodaFacetView.js
@@ -55,17 +55,17 @@ const QueryExplanation = {
     const spanify = (text, classNames) => {
       const span = document.createElement("span");
       span.setAttribute("class", classNames);
       span.textContent = text;
       this.node.appendChild(span);
       return span;
     };
 
-    const searchLabel = glodaFacetStrings.get("glodaFacetView.search.label");
+    const searchLabel = glodaFacetStrings.get("glodaFacetView.search.label2");
     spanify(searchLabel, "explanation-fulltext-label");
 
     const criteriaText = glodaFacetStrings.get(
       "glodaFacetView.constraints.query.fulltext." +
         (aMsgSearcher.andTerms ? "and" : "or") +
         "JoinWord"
     );
     for (let [iTerm, term] of aMsgSearcher.fulltextTerms.entries()) {
@@ -84,17 +84,17 @@ const QueryExplanation = {
       const spanify = (text, classNames) => {
         const span = document.createElement("span");
         span.setAttribute("class", classNames);
         span.textContent = text;
         this.node.appendChild(span);
         return span;
       };
 
-      let label = glodaFacetStrings.get("glodaFacetView.search.label");
+      let label = glodaFacetStrings.get("glodaFacetView.search.label2");
       spanify(label, "explanation-query-label");
 
       let constraintStrings = [];
       for (let constraint of msgQuery._constraints) {
         if (constraint[0] != 1) {
           // No idea what this is about.
           return;
         }
@@ -691,17 +691,17 @@ var FacetContext = {
           !faceter.constraint &&
           (!faceter.xblNode.explicit || faceter.type == "date")
         ) {
           faceter.xblNode.style.display = "none";
         } else {
           // otherwise, update
           faceter.xblNode.orderedGroups = faceter.orderedGroups;
           faceter.xblNode.build(false);
-          faceter.xblNode.style.display = "block";
+          faceter.xblNode.removeAttribute("style");
         }
       }
     }
 
     if (!this._timelineShown) {
       this._hideTimeline(true);
     }
 
@@ -721,32 +721,29 @@ var FacetContext = {
       this._activeSet.length
     );
     results.setMessages(this._activeSet.slice(0, numMessageToShow));
 
     let showLoading = document.getElementById("showLoading");
     showLoading.style.display = "none"; // Hide spinner, we're done thinking.
 
     let showEmpty = document.getElementById("showEmpty");
-    let dateToggle = document.getElementById("date-toggle");
+    let showAll = document.getElementById("gloda-showall");
     // Check for no messages at all.
     if (this._activeSet.length == 0) {
       showEmpty.style.display = "block";
-      dateToggle.style.display = "none";
+      showAll.style.display = "none";
     } else {
       showEmpty.style.display = "none";
-      dateToggle.style.display = "block";
+      showAll.style.display = "block";
     }
 
     let showMore = document.getElementById("showMore");
-    if (this._activeSet.length > numMessageToShow) {
-      showMore.style.display = "block";
-    } else {
-      showMore.style.display = "none";
-    }
+    showMore.style.display =
+      this._activeSet.length > numMessageToShow ? "block" : "none";
   },
 
   showMore() {
     this._numPages += 1;
     this._showResults();
   },
 
   zoomOut() {
@@ -783,28 +780,28 @@ var FacetContext = {
     let listener = () => {
       // Need to set overflow to visible so that the zoom button
       // is not cut off at the top, and overflow=hidden causes
       // the transition to not work as intended.
       facetDate.removeAttribute("style");
     };
     facetDate.addEventListener("transitionend", listener, { once: true });
     facetDate.removeAttribute("hide");
-    document.getElementById("date-toggle").removeAttribute("tucked");
+    document.getElementById("date-toggle").setAttribute("checked", "true");
     Services.prefs.setBoolPref("gloda.facetview.hidetimeline", false);
   },
 
   _hideTimeline(immediate) {
     let facetDate = document.getElementById("facet-date");
     if (immediate) {
       facetDate.style.display = "none";
     }
     facetDate.style.overflow = "hidden";
     facetDate.setAttribute("hide", "true");
-    document.getElementById("date-toggle").setAttribute("tucked", "true");
+    document.getElementById("date-toggle").removeAttribute("checked");
     Services.prefs.setBoolPref("gloda.facetview.hidetimeline", true);
   },
 
   _timelineShown: true,
 
   /** For use in hovering specific results. */
   fakeResultFaceter: {},
   /** For use in hovering specific results. */
--- a/mail/base/content/glodaFacetView.xhtml
+++ b/mail/base/content/glodaFacetView.xhtml
@@ -29,61 +29,63 @@
   <!-- Libs -->
   <script src="chrome://messenger/content/protovis-r2.6-modded.js"></script>
   <!-- Facet Binding Stuff that doesn't belong in XBL -->
   <script src="chrome://messenger/content/glodaFacetVis.js"></script>
 </head>
 <body id="body" onload="reachOutAndTouchFrame()"
       onmouseup="return clickOnBody(event)">
   <facet-popup-menu class="popup-menu" variety="invisible"/>
-  <div id="table">
-    <div>
-        <div class="facets facets-sidebar" id="facets">
-          <h1 id="filter-header-label">&glodaFacetView.filters.label;</h1>
-          <div>
-            <facet-boolean id="facet-fromMe" type="boolean" attr="fromMe" uninitialized="true"/>
-            <facet-boolean id="facet-toMe" type="boolean" attr="toMe" uninitialized="true"/>
-            <facet-boolean id="facet-star" type="boolean" attr="star" uninitialized="true"/><br/>
-            <facet-boolean-filtered id="facet-attachmentTypes"
-                                    type="boolean-filtered"
-                                    attr="attachmentTypes"
-                                    groupDisplayProperty="categoryLabel"
-                                    uninitialized="true"/>
-          </div>
-        </div>
-        <div id="main-column">
-          <div id="header">
-            <div id="date-toggle" class="date-toggle" tabindex="0" role="button"
-                 onclick="FacetContext.toggleTimeline()"
-                 onkeypress="if (event.charCode == KeyEvent.DOM_VK_SPACE) { FacetContext.toggleTimeline(); event.preventDefault() }"/>
-            <div id="search-value"/>
-            <div id="query-explanation"/>
+  <div id="gloda-facet-view">
+    <div class="facets facets-sidebar" id="facets">
+      <h1 id="filter-header-label">&glodaFacetView.filters.label;</h1>
+      <div>
+        <facet-boolean id="facet-fromMe" type="boolean" attr="fromMe" uninitialized="true"/>
+        <facet-boolean id="facet-toMe" type="boolean" attr="toMe" uninitialized="true"/>
+        <facet-boolean id="facet-star" type="boolean" attr="star" uninitialized="true"/><br/>
+        <facet-boolean-filtered id="facet-attachmentTypes"
+                                type="boolean-filtered"
+                                attr="attachmentTypes"
+                                groupDisplayProperty="categoryLabel"
+                                uninitialized="true"/>
+      </div>
+    </div>
+
+    <div id="main-column">
+      <div id="header">
+        <div id="query-explanation"/>
+        <a id="gloda-showall" class="results-message-showall-button"
+           title="&glodaFacetView.openEmailAsList.tooltip;"
+           onclick="FacetContext.showActiveSetInTab();"
+           onkeypress="if (event.charCode == KeyEvent.DOM_VK_SPACE) { FacetContext.showActiveSetInTab(); event.preventDefault(); }"
+           tabindex="0">
+          &glodaFacetView.openEmailAsList.label;
+        </a>
+      </div>
+      <div id="data-column">
+        <!-- facet-results-message is put before facet-date here so that it gets upgraded first.
+        facet-date uses width of facet-results-message for the visualization. Using order property
+        we can show facet-date before facet-results-message -->
+        <facet-results-message id="results" class="results"/>
+        <facet-date id="facet-date" class="facetious" type="date"/>
+        <div class="loading" id="showLoading">
+          <span class="loading">
+            <img class="loading"
+                 src="chrome://global/skin/icons/loading.png"/>
+            &glodaFacetView.loading.label;
+          </span>
           </div>
-          <div id="data-column">
-            <!-- facet-results-message is put before facet-date here so that it gets upgraded first.
-            facet-date uses width of facet-results-message for the visualization. Using order property
-            we can show facet-date before facet-results-message -->
-            <facet-results-message id="results" class="results"/>
-            <facet-date id="facet-date" class="facetious" type="date"/>
-            <div class="loading" id="showLoading">
-              <span class="loading">
-                <img class="loading"
-                     src="chrome://global/skin/icons/loading.png"/>
-                &glodaFacetView.loading.label;
-              </span>
-             </div>
-            <div class="empty"	id="showEmpty">
-              <span class="empty">
-                <img class="empty"
-                     src="chrome://messenger/skin/icons/empty-search-results.png"/><br/>
-                &glodaFacetView.empty.label;
-              </span>
-              </div>
-            <div class="show-more" id="showMore" tabindex="0" role="button"
-                 onclick="FacetContext.showMore()"
-                 onkeypress="if (event.charCode == KeyEvent.DOM_VK_SPACE) { FacetContext.showMore(); event.preventDefault() }"
-                 >&glodaFacetView.pageMore.label;</div>
+        <div id="showEmpty" class="empty">
+          <span class="empty">
+            <img class="empty"
+                 src="chrome://messenger/skin/icons/empty-search-results.png"/><br/>
+            &glodaFacetView.empty.label;
+          </span>
           </div>
-        </div>
+        <div class="show-more" id="showMore" tabindex="0" role="button"
+             onclick="FacetContext.showMore()"
+             onkeypress="if (event.charCode == KeyEvent.DOM_VK_SPACE) { FacetContext.showMore(); event.preventDefault() }"
+             >&glodaFacetView.pageMore.label;</div>
       </div>
+    </div>
   </div>
 </body>
 </html>
--- a/mail/locales/en-US/chrome/messenger/glodaFacetView.dtd
+++ b/mail/locales/en-US/chrome/messenger/glodaFacetView.dtd
@@ -13,8 +13,17 @@
 
 <!-- LOCALIZATION NOTE (glodaFacetView.empty.label): Label that appears when
      there are no results that match the search query. -->
 <!ENTITY glodaFacetView.empty.label "No messages match your search">
 
 <!-- LOCALIZATION NOTE (glodaFacetView.pageMore.label): Label at the bottom
      of the results list to show more hits. -->
 <!ENTITY glodaFacetView.pageMore.label "More &#187;">
+
+<!-- LOCALIZATION NOTE(glodaFacetView.results.message.openEmailAsList.label2): The
+     label for the button/link that causes us to display all of the emails in
+     the active set in a new thread pane display tab. -->
+<!ENTITY glodaFacetView.openEmailAsList.label "Show results as list">
+
+<!-- LOCALIZATION NOTE(glodaFacetView.results.message.openEmailAsList.tooltip):
+     The tooltip to display when hovering over the openEmailAsList label. -->
+<!ENTITY glodaFacetView.openEmailAsList.tooltip "Show all of the email messages in the active set in a new tab">
--- a/mail/locales/en-US/chrome/messenger/glodaFacetView.properties
+++ b/mail/locales/en-US/chrome/messenger/glodaFacetView.properties
@@ -10,20 +10,20 @@ glodaFacetView.tab.query.label=Search
 
 # LOCALIZATION NOTE (glodaFacetView.tab.search.label):
 #  The tab title to display for tabs with a new gloda (global database)
 #  user search (rather than a query or collection) without a search string.
 #  After the search has been started, we just display the search string entered
 #  by the user.
 glodaFacetView.tab.search.label=Search
 
-# LOCALIZATION NOTE(glodaFacetView.search.label):
+# LOCALIZATION NOTE(glodaFacetView.search.label2):
 #  The heading for the search page.
 #  A short description of user's search query will be appended.
-glodaFacetView.search.label=Search
+glodaFacetView.search.label2=Results for:
 
 # LOCALIZATION NOTE(glodaFacetView.constraints.query.fulltext.label):
 #  The label to display to describe when our base query was a fulltext search
 #  across messages.  The value is displayed following the label.
 glodaFacetView.constraints.query.fulltext.label=Searching for #1
 glodaFacetView.constraints.query.fulltext.andJoinWord=and
 glodaFacetView.constraints.query.fulltext.orJoinWord=or
 
@@ -140,33 +140,23 @@ glodaFacetView.results.header.countLabel
 glodaFacetView.results.header.countLabel.ofN=of #1;of #1
 # LOCALIZATION NOTE(glodaFacetView.results.header.countLabel.grouping):
 #  Combines the pluralized
 #  "glodaFacetView.results.header.countLabel.NMessages" string (as #1) with
 #  the pluralized "glodaFacetView.results.header.countLabel.ofN" (as #2)
 #  to make a single label.
 glodaFacetView.results.header.countLabel.grouping=#1 #2
 
-# LOCALIZATION NOTE(glodaFacetView.results.message.openEmailAsList.label): The
-#  label for the button/link that causes us to display all of the emails in
-#  the active set in a new thread pane display tab.
-glodaFacetView.results.message.openEmailAsList.label=Open email as list
-# LOCALIZATION NOTE(glodaFacetView.results.message.openEmailAsList.tooltip):
-#  The tooltip to display when hovering over the openEmailAsList label.
-glodaFacetView.results.message.openEmailAsList.tooltip=Show all of the email messages in the active set in a new tab.
-
-# LOCALIZATION NOTE(glodaFacetView.results.message.sort.label): The
-#  label next to the choice of sort order
-glodaFacetView.results.message.sort.label=sort by:
-# LOCALIZATION NOTE(glodaFacetView.results.message.sort.relevance):
+glodaFacetView.results.message.timeline.label=Toggle timeline
+# LOCALIZATION NOTE(glodaFacetView.results.message.sort.relevance2):
 # a clickable label causing the sort to be done by most relevant messages first.
-glodaFacetView.results.message.sort.relevance=relevance
-# LOCALIZATION NOTE(glodaFacetView.results.message.sort.date):
+glodaFacetView.results.message.sort.relevance2=Sort by Relevance
+# LOCALIZATION NOTE(glodaFacetView.results.message.sort.date2):
 # a clickable label causing the sort to be done by most recent messages first.
-glodaFacetView.results.message.sort.date=date
+glodaFacetView.results.message.sort.date2=Sort by Date
 
 # LOCALIZATION NOTE(glodaFacetView.results.message.recipientSeparator): This is
 # the string in between the names of recipients (see
 # glodaFacetView.results.message.andOthers for more information).  The \u0020
 # character is a Unicode space character, which is needed as otherwise the
 # trailing whitespace is trimmed before it gets to the code.
 glodaFacetView.results.message.recipientSeparator=,\u0020
 
--- a/mail/themes/linux/mail/glodaFacetView.css
+++ b/mail/themes/linux/mail/glodaFacetView.css
@@ -18,32 +18,21 @@
   --buttonHoverTextColor: -moz-ButtonHoverText;
 }
 
 .facets-sidebar {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
-#table {
-  background-color: -moz-Field;
-  color: -moz-FieldText;
-}
-
 .facet-more,
 .show-more {
   padding: 0;
 }
 
-.facet-more[needed="true"],
-.results-message-showall-button,
-.results-message-sort-bar {
-  font-size: x-small;
-}
-
 .barry {
   border-top: 1px solid GrayText;
 }
 
 .bar {
   border-bottom: 1px solid GrayText;
 }
 
--- a/mail/themes/osx/mail/glodaFacetView.css
+++ b/mail/themes/osx/mail/glodaFacetView.css
@@ -18,21 +18,16 @@
   --buttonHoverTextColor: -moz-ButtonHoverText;
 }
 
 .facets-sidebar {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
-#table {
-  background-color: -moz-Field;
-  color: -moz-FieldText;
-}
-
 .barry {
   border-top: 1px solid GrayText;
 }
 
 .bar {
   border-bottom: 1px solid GrayText;
 }
 
--- a/mail/themes/shared/jar.inc.mn
+++ b/mail/themes/shared/jar.inc.mn
@@ -65,26 +65,28 @@
   skin/classic/messenger/icons/move-bottom.svg                (../shared/mail/icons/move-bottom.svg)
   skin/classic/messenger/icons/move-down.svg                  (../shared/mail/icons/move-down.svg)
   skin/classic/messenger/icons/move-together.svg              (../shared/mail/icons/move-together.svg)
   skin/classic/messenger/icons/move-top.svg                   (../shared/mail/icons/move-top.svg)
   skin/classic/messenger/icons/move-up.svg                    (../shared/mail/icons/move-up.svg)
   skin/classic/messenger/icons/navigation.svg                 (../shared/mail/icons/navigation.svg)
   skin/classic/messenger/icons/new.svg                        (../shared/mail/icons/new.svg)
   skin/classic/messenger/icons/newmsg.svg                     (../shared/mail/icons/newmsg.svg)
+  skin/classic/messenger/icons/new-window.svg                 (../shared/mail/icons/new-window.svg)
   skin/classic/messenger/icons/nextmsg.svg                    (../shared/mail/icons/nextmsg.svg)
   skin/classic/messenger/icons/nextunread.svg                 (../shared/mail/icons/nextunread.svg)
   skin/classic/messenger/icons/overflow-indicator.png         (../shared/mail/icons/overflow-indicator.png)
   skin/classic/messenger/icons/overflow.svg                   (../shared/mail/icons/overflow.svg)
   skin/classic/messenger/icons/paste.svg                      (../shared/mail/icons/paste.svg)
   skin/classic/messenger/icons/pluginBlocked.svg              (../shared/mail/icons/pluginBlocked.svg)
   skin/classic/messenger/icons/previousmsg.svg                (../shared/mail/icons/previousmsg.svg)
   skin/classic/messenger/icons/previousunread.svg             (../shared/mail/icons/previousunread.svg)
   skin/classic/messenger/icons/print.svg                      (../shared/mail/icons/print.svg)
   skin/classic/messenger/icons/panel-icon-magnifier.svg       (../shared/mail/icons/panel-icon-magnifier.svg)
+  skin/classic/messenger/icons/popular.svg                    (../shared/mail/icons/popular.svg)
   skin/classic/messenger/icons/quit.svg                       (../shared/mail/icons/quit.svg)
   skin/classic/messenger/icons/quote.svg                      (../shared/mail/icons/quote.svg)
   skin/classic/messenger/icons/readcol.svg                    (../shared/mail/icons/readcol.svg)
   skin/classic/messenger/icons/remote-blocked.svg             (../shared/mail/icons/remote-blocked.svg)
   skin/classic/messenger/icons/reply.svg                      (../shared/mail/icons/reply.svg)
   skin/classic/messenger/icons/replyall.svg                   (../shared/mail/icons/replyall.svg)
   skin/classic/messenger/icons/replylist.svg                  (../shared/mail/icons/replylist.svg)
   skin/classic/messenger/icons/search-glass.svg               (../shared/mail/icons/search-glass.svg)
new file mode 100644
--- /dev/null
+++ b/mail/themes/shared/mail/icons/new-window.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" d="M15.5 12H13V9.5a.5.5 0 0 0-1 0V12H9.5a.5.5 0 0 0 0 1H12v2.5a.5.5 0 0 0 1 0V13h2.5a.5.5 0 0 0 0-1z"></path><path fill="context-fill" d="M16 4a3 3 0 0 0-3-3H3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h4.03v-.006a.994.994 0 0 0 0-1.987V13H3a1 1 0 0 1-1-1V6h12v1.952h.01c0 .017-.01.031-.01.048a1 1 0 0 0 2 0c0-.017-.009-.031-.01-.048H16zM2 5V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1z"></path></svg>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/mail/themes/shared/mail/icons/popular.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" d="M15.207 2.793a1 1 0 0 0-.932-.268l-6.5 1.5a1 1 0 1 0 .45 1.949l3.1-.716L6.5 10.086 5.207 8.793a1 1 0 0 0-1.414 0l-3 3a1 1 0 1 0 1.414 1.414L4.5 10.914l1.293 1.293a1 1 0 0 0 1.414 0l5.535-5.535-.716 3.1a1 1 0 0 0 .75 1.2A1.025 1.025 0 0 0 13 11a1 1 0 0 0 .974-.775l1.5-6.5a1 1 0 0 0-.267-.932z"></path></svg>
\ No newline at end of file
--- a/mail/themes/windows/mail/glodaFacetView.css
+++ b/mail/themes/windows/mail/glodaFacetView.css
@@ -28,21 +28,16 @@
     --borderRadius: 2px;
   }
 
   .facets-sidebar {
     background-color: #eef3fa;
   }
 }
 
-#table {
-  background-color: -moz-Field;
-  color: -moz-FieldText;
-}
-
 .barry {
   border-top: 1px solid GrayText;
 }
 
 .bar {
   border-bottom: 1px solid GrayText;
 }