1 add_task(async function () {
2 await openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true });
3 await gBrowser.contentWindow.gMainPane._selectDefaultLanguageGroupPromise;
4 await TestUtils.waitForCondition(
5 () => !gBrowser.contentWindow.Preferences.updateQueued
8 let doc = gBrowser.contentDocument;
9 let contentWindow = gBrowser.contentWindow;
10 var langGroup = Services.prefs.getComplexValue(
11 "font.language.group",
12 Ci.nsIPrefLocalizedString
15 contentWindow.Preferences.get("font.language.group").value,
17 "Language group should be set correctly."
20 let defaultFontType = Services.prefs.getCharPref("font.default." + langGroup);
21 let fontFamilyPref = "font.name." + defaultFontType + "." + langGroup;
22 let fontFamily = Services.prefs.getCharPref(fontFamilyPref);
23 let fontFamilyField = doc.getElementById("defaultFont");
24 is(fontFamilyField.value, fontFamily, "Font family should be set correctly.");
26 function dispatchMenuItemCommand(menuItem) {
27 const cmdEvent = doc.createEvent("xulcommandevent");
28 cmdEvent.initCommandEvent(
42 menuItem.dispatchEvent(cmdEvent);
46 * Return a promise that resolves when the fontFamilyPref changes.
48 * Font prefs are the only ones whose form controls set "delayprefsave",
49 * which delays the pref change when a user specifies a new value
50 * for the pref. Thus, in order to confirm that the pref gets changed
51 * when the test selects a new value in a font field, we need to await
52 * the change. Awaiting this function does so for fontFamilyPref.
54 function fontFamilyPrefChanged() {
55 return new Promise(resolve => {
57 observe(aSubject, aTopic, aData) {
58 // Check for an exact match to avoid the ambiguity of nsIPrefBranch's
59 // prefix-matching algorithm for notifying pref observers.
60 if (aData == fontFamilyPref) {
61 Services.prefs.removeObserver(fontFamilyPref, observer);
66 Services.prefs.addObserver(fontFamilyPref, observer);
70 const menuItems = fontFamilyField.querySelectorAll("menuitem");
71 Assert.greater(menuItems.length, 1, "There are multiple font menuitems.");
72 ok(menuItems[0].selected, "The first (default) font menuitem is selected.");
74 dispatchMenuItemCommand(menuItems[1]);
75 ok(menuItems[1].selected, "The second font menuitem is selected.");
77 await fontFamilyPrefChanged();
78 fontFamily = Services.prefs.getCharPref(fontFamilyPref);
79 is(fontFamilyField.value, fontFamily, "The font family has been updated.");
81 dispatchMenuItemCommand(menuItems[0]);
83 menuItems[0].selected,
84 "The first (default) font menuitem is selected again."
87 await fontFamilyPrefChanged();
88 fontFamily = Services.prefs.getCharPref(fontFamilyPref);
89 is(fontFamilyField.value, fontFamily, "The font family has been updated.");
91 let defaultFontSize = Services.prefs.getIntPref(
92 "font.size.variable." + langGroup
94 let fontSizeField = doc.getElementById("defaultFontSize");
98 "Font size should be set correctly."
101 let promiseSubDialogLoaded = promiseLoadSubDialog(
102 "chrome://browser/content/preferences/dialogs/fonts.xhtml"
104 doc.getElementById("advancedFonts").click();
105 let win = await promiseSubDialogLoaded;
108 // Simulate a dumb font backend.
109 win.FontBuilder._enumerator = {
110 _list: ["MockedFont1", "MockedFont2", "MockedFont3"],
112 EnumerateFontsAsync(lang, type) {
113 return Promise.resolve(this._list);
115 EnumerateAllFontsAsync() {
116 return Promise.resolve(this._list);
119 return this._defaultFont;
121 getStandardFamilyName(name) {
125 win.FontBuilder._allFonts = null;
126 win.FontBuilder._langGroupSupported = false;
128 let langGroupElement = win.Preferences.get("font.language.group");
129 let selectLangsField = doc.getElementById("selectLangs");
130 let serifField = doc.getElementById("serif");
131 let armenian = "x-armn";
132 let western = "x-western";
134 // Await rebuilding of the font lists, which happens asynchronously in
135 // gFontsDialog._selectLanguageGroup. Testing code needs to call this
136 // function and await its resolution after changing langGroupElement's value
137 // (or doing anything else that triggers a call to _selectLanguageGroup).
138 function fontListsRebuilt() {
139 return win.gFontsDialog._selectLanguageGroupPromise;
142 langGroupElement.value = armenian;
143 await fontListsRebuilt();
144 selectLangsField.value = armenian;
145 is(serifField.value, "", "Font family should not be set.");
147 let armenianSerifElement = win.Preferences.get("font.name.serif.x-armn");
149 langGroupElement.value = western;
150 await fontListsRebuilt();
151 selectLangsField.value = western;
153 // Simulate a font backend supporting language-specific enumeration.
154 // NB: FontBuilder has cached the return value from EnumerateAllFonts(),
155 // so _allFonts will always have 3 elements regardless of subsequent
157 win.FontBuilder._enumerator._list = ["MockedFont2"];
159 langGroupElement.value = armenian;
160 await fontListsRebuilt();
161 selectLangsField.value = armenian;
165 "Font family should still be empty for indicating using 'default' font."
168 langGroupElement.value = western;
169 await fontListsRebuilt();
170 selectLangsField.value = western;
172 // Simulate a system that has no fonts for the specified language.
173 win.FontBuilder._enumerator._list = [];
175 langGroupElement.value = armenian;
176 await fontListsRebuilt();
177 selectLangsField.value = armenian;
178 is(serifField.value, "", "Font family should not be set.");
180 // Setting default font to "MockedFont3". Then, when serifField.value is
181 // empty, it should indicate using "MockedFont3" but it shouldn't be saved
182 // to "MockedFont3" in the pref. It should be resolved at runtime.
183 win.FontBuilder._enumerator._list = [
188 win.FontBuilder._enumerator._defaultFont = "MockedFont3";
189 langGroupElement.value = armenian;
190 await fontListsRebuilt();
191 selectLangsField.value = armenian;
195 "Font family should be empty even if there is a default font."
198 armenianSerifElement.value = "MockedFont2";
199 serifField.value = "MockedFont2";
203 'Font family should be "MockedFont2" for now.'
206 langGroupElement.value = western;
207 await fontListsRebuilt();
208 selectLangsField.value = western;
209 is(serifField.value, "", "Font family of other language should not be set.");
211 langGroupElement.value = armenian;
212 await fontListsRebuilt();
213 selectLangsField.value = armenian;
217 "Font family should not be changed even after switching the language."
220 // If MochedFont2 is removed from the system, the value should be treated
221 // as empty (i.e., 'default' font) after rebuilding the font list.
222 win.FontBuilder._enumerator._list = ["MockedFont1", "MockedFont3"];
223 win.FontBuilder._enumerator._allFonts = ["MockedFont1", "MockedFont3"];
224 serifField.removeAllItems(); // This will cause rebuilding the font list from available fonts.
225 langGroupElement.value = armenian;
226 await fontListsRebuilt();
227 selectLangsField.value = armenian;
231 "Font family should become empty due to the font uninstalled."
234 gBrowser.removeCurrentTab();