Bug 1472966 - Limit list of used fonts to 3 and put others in a collapsed list. r=gl draft
authorRazvan Caliman <rcaliman@mozilla.com>
Tue, 03 Jul 2018 20:05:40 +0200
changeset 814078 efbaa1dab4229e3d7caa83f6415d6a4d589f9cb2
parent 814077 ebfbf406f0fc61b79402af791ab9cbd8b32ba2bf
child 814079 71b436c398ffb7de1213830d4449deadfe33c021
push id115083
push userbmo:rcaliman@mozilla.com
push dateWed, 04 Jul 2018 12:05:55 +0000
reviewersgl
bugs1472966
milestone63.0a1
Bug 1472966 - Limit list of used fonts to 3 and put others in a collapsed list. r=gl MozReview-Commit-ID: AYKkU7MsMWD
devtools/client/inspector/fonts/components/FontEditor.js
devtools/client/locales/en-US/font-inspector.properties
devtools/client/themes/fonts.css
--- a/devtools/client/inspector/fonts/components/FontEditor.js
+++ b/devtools/client/inspector/fonts/components/FontEditor.js
@@ -12,16 +12,20 @@ const FontMeta = createFactory(require("
 const FontPropertyValue = createFactory(require("./FontPropertyValue"));
 const FontSize = createFactory(require("./FontSize"));
 const FontStyle = createFactory(require("./FontStyle"));
 const FontWeight = createFactory(require("./FontWeight"));
 
 const { getStr } = require("../utils/l10n");
 const Types = require("../types");
 
+// Maximum number of font families to be shown by default. Any others will be hidden
+// under a collapsed <details> element with a toggle to reveal them.
+const MAX_FONTS = 3;
+
 class FontEditor extends PureComponent {
   static get propTypes() {
     return {
       fontEditor: PropTypes.shape(Types.fontEditor).isRequired,
       onInstanceChange: PropTypes.func.isRequired,
       onPropertyChange: PropTypes.func.isRequired,
       onToggleFontHighlight: PropTypes.func.isRequired,
     };
@@ -92,73 +96,100 @@ class FontEditor extends PureComponent {
         },
         family
       );
     });
 
     return dom.details(
       {},
       dom.summary(
-        {
-          className: "font-family-unused-header",
-        },
+        {},
         getStr("fontinspector.familiesNotUsedLabel")
       ),
       familiesList
     );
   }
 
   /**
    * Render font family, font name, and metadata for all fonts used on selected node.
    *
    * @param {Array} fonts
    *        Fonts used on selected node.
    * @param {Array} families
    *        Font familes declared on selected node.
-   * @param {Function} onToggleFontHighlight
-   *        Callback to trigger in-context highlighting of text that uses a font.
    * @return {DOMNode}
    */
-  renderFontFamily(fonts, families, onToggleFontHighlight) {
+  renderFontFamily(fonts, families) {
     if (!fonts.length) {
       return null;
     }
 
-    const fontList = dom.ul(
-      {
-        className: "fonts-list"
-      },
-      fonts.map(font => {
-        return dom.li(
-          {},
-          FontMeta({ font, onToggleFontHighlight })
+    const topUsedFontsList = this.renderFontList(fonts.slice(0, MAX_FONTS));
+    const moreUsedFontsList = this.renderFontList(fonts.slice(MAX_FONTS, fonts.length));
+    const moreUsedFonts = moreUsedFontsList === null
+      ? null
+      : dom.details({},
+          dom.summary({},
+            dom.span({ className: "label-open" }, getStr("fontinspector.seeMore")),
+            dom.span({ className: "label-close" }, getStr("fontinspector.seeLess"))
+          ),
+          moreUsedFontsList
         );
-      })
-    );
 
     return dom.label(
       {
         className: "font-control font-control-family",
       },
       dom.span(
         {
           className: "font-control-label",
         },
         getStr("fontinspector.fontFamilyLabel")
       ),
       dom.div(
         {
           className: "font-control-box",
         },
-        fontList,
+        topUsedFontsList,
+        moreUsedFonts,
         this.renderFamilesNotUsed(families.notUsed)
       )
     );
   }
 
+  /**
+   * Given an array of fonts, get an unordered list with rendered FontMeta components.
+   * If the array of fonts is empty, return null.
+   *
+   * @param {Array} fonts
+   *        Array of objects with information about fonts used on the selected node.
+   * @return {DOMNode|null}
+   */
+  renderFontList(fonts = []) {
+    if (!fonts.length) {
+      return null;
+    }
+
+    return dom.ul(
+      {
+        className: "fonts-list"
+      },
+      fonts.map(font => {
+        return dom.li(
+          {},
+          FontMeta({
+            font,
+            key: font.name,
+            onToggleFontHighlight: this.props.onToggleFontHighlight
+          })
+        );
+      })
+    );
+  }
+
   renderFontSize(value) {
     return value && FontSize({
       onChange: this.props.onPropertyChange,
       value,
     });
   }
 
   renderFontStyle(value) {
@@ -239,17 +270,17 @@ class FontEditor extends PureComponent {
       {
         className: "devtools-sidepanel-no-result"
       },
       getStr("fontinspector.noFontsOnSelectedElement")
     );
   }
 
   render() {
-    const { fontEditor, onToggleFontHighlight } = this.props;
+    const { fontEditor } = this.props;
     const { fonts, families, axes, instance, properties } = fontEditor;
     // Pick the first font to show editor controls regardless of how many fonts are used.
     const font = fonts[0];
     const hasFontAxes = font && font.variationAxes;
     const hasFontInstances = font && font.variationInstances
       && font.variationInstances.length > 0;
     const hasSlantOrItalicAxis = hasFontAxes && font.variationAxes.find(axis => {
       return axis.tag === "slnt" || axis.tag === "ital";
@@ -262,17 +293,17 @@ class FontEditor extends PureComponent {
 
     return dom.div(
       {
         id: "font-editor"
       },
       // Render empty state message for nodes that don't have font properties.
       !hasWeight && this.renderWarning(),
       // Always render UI for font family, format and font file URL.
-      this.renderFontFamily(fonts, families, onToggleFontHighlight),
+      this.renderFontFamily(fonts, families),
       // Render UI for font variation instances if they are defined.
       hasFontInstances && this.renderInstances(font.variationInstances, instance),
       // Always render UI for font size.
       this.renderFontSize(properties["font-size"]),
       // Render UI for font weight if no "wght" registered axis is defined.
       !hasWeightAxis && this.renderFontWeight(properties["font-weight"]),
       // Render UI for font style if no "slnt" or "ital" registered axis is defined.
       !hasSlantOrItalicAxis && this.renderFontStyle(properties["font-style"]),
--- a/devtools/client/locales/en-US/font-inspector.properties
+++ b/devtools/client/locales/en-US/font-inspector.properties
@@ -59,8 +59,14 @@ fontinspector.fontWeightLabel=Weight
 
 # LOCALIZATION NOTE (fontinspector.fontItalicLabel): This label is shown next to the UI
 # in the font editor which allows the user to change the style of the font to italic.
 fontinspector.fontItalicLabel=Italic
 
 # LOCALIZATION NOTE (fontinspector.familiesNotUsedLabel): Label for the list in the font
 # editor which contains the names of font families declared but not used.
 fontinspector.familiesNotUsedLabel=Unused font families
+
+# LOCALIZATION NOTE (fontinspector.showMore): Label for a collapsed list of fonts.
+fontinspector.seeMore=See more
+
+# LOCALIZATION NOTE (fontinspector.showLess): Label for an expanded list of fonts.
+fontinspector.seeLess=See less
--- a/devtools/client/themes/fonts.css
+++ b/devtools/client/themes/fonts.css
@@ -10,16 +10,37 @@
   height: 100%;
   overflow: auto;
 }
 
 #font-container {
   flex: auto;
 }
 
+#font-editor summary {
+  -moz-user-select: none;
+  cursor: pointer;
+  margin-bottom: .7em;
+  width: fit-content;
+  width: -moz-fit-content;
+}
+
+#font-editor details .label-open,
+#font-editor details .label-close {
+  display: none;
+}
+
+#font-editor details[open] .label-close {
+  display: inline-block;
+}
+
+#font-editor details:not([open]) .label-open {
+  display: inline-block;
+}
+
 .fonts-list {
   padding: 0;
   margin: 0;
   list-style: none;
 }
 
 .font {
   border: 1px solid var(--theme-splitter-color);
@@ -151,22 +172,16 @@
   display: inline-block;
   flex: 1;
   font-size: 12px;
   min-width: 80px;
   margin-right: 10px;
   -moz-user-select: none;
 }
 
-.font-family-unused-header {
-  -moz-user-select: none;
-  margin-bottom: .7em;
-  cursor: pointer;
-}
-
 .font-family-unused {
   margin-bottom: .3em;
   color: var(--grey-50);
 }
 
 .font-instance-select:active{
   outline: none;
 }