Bug 1254978 - Set blank if the current font is not installed and the font backend does not support language-specific enumeration. r=Gijs
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Mon, 14 Mar 2016 22:01:05 +0900
changeset 339984 7277824fbd1dea85a59d0bade0a44ccfb5186703
parent 339983 2bef59a4476a99e0796bde9502c1bf0744f97182
child 339985 5be369e4bcbfc25c10e02d1922beb98072e000cd
push id12864
push usermratcliffe@mozilla.com
push dateMon, 14 Mar 2016 17:17:30 +0000
reviewersGijs
bugs1254978
milestone48.0a1
Bug 1254978 - Set blank if the current font is not installed and the font backend does not support language-specific enumeration. r=Gijs
browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
toolkit/mozapps/preferences/fontbuilder.js
--- a/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
+++ b/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
@@ -15,10 +15,62 @@ add_task(function() {
   let fontFamily = Services.prefs.getCharPref("font.name." + defaultFontType + "." + langGroup);
   let fontFamilyField = doc.getElementById("defaultFont");
   is(fontFamilyField.value, fontFamily, "Font family should be set correctly.");
 
   let defaultFontSize = Services.prefs.getIntPref("font.size.variable." + langGroup);
   let fontSizeField = doc.getElementById("defaultFontSize");
   is(fontSizeField.value, defaultFontSize, "Font size should be set correctly.");
 
+  doc.getElementById("advancedFonts").click();
+  let win = yield promiseLoadSubDialog("chrome://browser/content/preferences/fonts.xul");
+  doc = win.document;
+
+  // Simulate a dumb font backend.
+  win.FontBuilder._enumerator = {
+    _list: ["MockedFont1", "MockedFont2", "MockedFont3"],
+    EnumerateFonts: function(lang, type, list) {
+      return this._list;
+    },
+    EnumerateAllFonts: function() {
+      return this._list;
+    },
+    getDefaultFont: function() { return null; },
+    getStandardFamilyName: function(name) { return name; },
+  };
+  win.FontBuilder._allFonts = null;
+  win.FontBuilder._langGroupSupported = false;
+
+  let langGroupElement = doc.getElementById("font.language.group");
+  let selectLangsField = doc.getElementById("selectLangs");
+  let serifField = doc.getElementById("serif");
+  let armenian = "x-armn";
+  let western = "x-western";
+
+  langGroupElement.value = armenian;
+  selectLangsField.value = armenian;
+  is(serifField.value, "", "Font family should not be set.");
+
+  langGroupElement.value = western;
+  selectLangsField.value = western;
+
+  // Simulate a font backend supporting language-specific enumeration.
+  // NB: FontBuilder has cached the return value from EnumerateAllFonts(),
+  // so _allFonts will always have 3 elements regardless of subsequent
+  // _list changes.
+  win.FontBuilder._enumerator._list = ["MockedFont2"];
+
+  langGroupElement.value = armenian;
+  selectLangsField.value = armenian;
+  is(serifField.value, "MockedFont2", "Font family should be set.");
+
+  langGroupElement.value = western;
+  selectLangsField.value = western;
+
+  // Simulate a system that has no fonts for the specified language.
+  win.FontBuilder._enumerator._list = [];
+
+  langGroupElement.value = armenian;
+  selectLangsField.value = armenian;
+  is(serifField.value, "", "Font family should not be set.");
+
   gBrowser.removeCurrentTab();
 });
--- a/toolkit/mozapps/preferences/fontbuilder.js
+++ b/toolkit/mozapps/preferences/fontbuilder.js
@@ -11,16 +11,17 @@ var FontBuilder = {
     if (!this._enumerator) {
       this._enumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
                                    .createInstance(Components.interfaces.nsIFontEnumerator);
     }
     return this._enumerator;
   },
 
   _allFonts: null,
+  _langGroupSupported: false,
   buildFontList: function (aLanguage, aFontType, aMenuList)
   {
     // Reset the list
     while (aMenuList.hasChildNodes())
       aMenuList.removeChild(aMenuList.firstChild);
 
     var defaultFont = null;
     // Load Font Lists
@@ -57,16 +58,17 @@ var FontBuilder = {
         menuitem.setAttribute("value", fonts[i]);
         menuitem.setAttribute("label", fonts[i]);
         popup.appendChild(menuitem);
       }
     }
 
     // Build the UI for the remaining fonts.
     if (this._allFonts.length > fonts.length) {
+      this._langGroupSupported = true;
       // Both lists are sorted, and the Fonts-By-Type list is a subset of the
       // All-Fonts list, so walk both lists side-by-side, skipping values we've
       // already created menu items for.
       var builtItem = separator ? separator.nextSibling : popup.firstChild;
       var builtItemValue = builtItem ? builtItem.getAttribute("value") : null;
 
       separator = document.createElement("menuseparator");
       popup.appendChild(separator);
@@ -97,17 +99,20 @@ var FontBuilder = {
     if (preference.value) {
       let fontItems = aElement.getElementsByAttribute("value", preference.value);
 
       // There is a setting that actually is in the list. Respect it.
       if (fontItems.length)
         return undefined;
     }
 
-    let defaultValue = aElement.firstChild.firstChild.getAttribute("value");
+    // The first item will be a reasonable choice only if the font backend
+    // supports language-specific enumaration.
+    let defaultValue = this._langGroupSupported ?
+                       aElement.firstChild.firstChild.getAttribute("value") : "";
     let fontNameList = preference.name.replace(".name.", ".name-list.");
     let prefFontNameList = document.getElementById(fontNameList);
     if (!prefFontNameList || !prefFontNameList.value)
       return defaultValue;
 
     let fontNames = prefFontNameList.value.split(",");
 
     for (let i = 0; i < fontNames.length; ++i) {