Home | History | Annotate | Download | only in fontSettings
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // The scripts supported by the Font Settings Extension API.
      6 var scripts = [
      7   { scriptCode: 'Zyyy', scriptName: 'Default'},
      8   { scriptCode: 'Afak', scriptName: 'Afaka'},
      9   { scriptCode: 'Arab', scriptName: 'Arabic'},
     10   { scriptCode: 'Armi', scriptName: 'Imperial Aramaic'},
     11   { scriptCode: 'Armn', scriptName: 'Armenian'},
     12   { scriptCode: 'Avst', scriptName: 'Avestan'},
     13   { scriptCode: 'Bali', scriptName: 'Balinese'},
     14   { scriptCode: 'Bamu', scriptName: 'Bamum'},
     15   { scriptCode: 'Bass', scriptName: 'Bassa Vah'},
     16   { scriptCode: 'Batk', scriptName: 'Batak'},
     17   { scriptCode: 'Beng', scriptName: 'Bengali'},
     18   { scriptCode: 'Blis', scriptName: 'Blissymbols'},
     19   { scriptCode: 'Bopo', scriptName: 'Bopomofo'},
     20   { scriptCode: 'Brah', scriptName: 'Brahmi'},
     21   { scriptCode: 'Brai', scriptName: 'Braille'},
     22   { scriptCode: 'Bugi', scriptName: 'Buginese'},
     23   { scriptCode: 'Buhd', scriptName: 'Buhid'},
     24   { scriptCode: 'Cakm', scriptName: 'Chakma'},
     25   { scriptCode: 'Cans', scriptName: 'Unified Canadian Aboriginal Syllabics'},
     26   { scriptCode: 'Cari', scriptName: 'Carian'},
     27   { scriptCode: 'Cham', scriptName: 'Cham'},
     28   { scriptCode: 'Cher', scriptName: 'Cherokee'},
     29   { scriptCode: 'Cirt', scriptName: 'Cirth'},
     30   { scriptCode: 'Copt', scriptName: 'Coptic'},
     31   { scriptCode: 'Cprt', scriptName: 'Cypriot'},
     32   { scriptCode: 'Cyrl', scriptName: 'Cyrillic'},
     33   { scriptCode: 'Cyrs', scriptName: 'Old Church Slavonic Cyrillic'},
     34   { scriptCode: 'Deva', scriptName: 'Devanagari'},
     35   { scriptCode: 'Dsrt', scriptName: 'Deseret'},
     36   { scriptCode: 'Dupl', scriptName: 'Duployan shorthand'},
     37   { scriptCode: 'Egyd', scriptName: 'Egyptian demotic'},
     38   { scriptCode: 'Egyh', scriptName: 'Egyptian hieratic'},
     39   { scriptCode: 'Egyp', scriptName: 'Egyptian hieroglyphs'},
     40   { scriptCode: 'Elba', scriptName: 'Elbasan'},
     41   { scriptCode: 'Ethi', scriptName: 'Ethiopic'},
     42   { scriptCode: 'Geok', scriptName: 'Georgian Khutsuri'},
     43   { scriptCode: 'Geor', scriptName: 'Georgian'},
     44   { scriptCode: 'Glag', scriptName: 'Glagolitic'},
     45   { scriptCode: 'Goth', scriptName: 'Gothic'},
     46   { scriptCode: 'Gran', scriptName: 'Grantha'},
     47   { scriptCode: 'Grek', scriptName: 'Greek'},
     48   { scriptCode: 'Gujr', scriptName: 'Gujarati'},
     49   { scriptCode: 'Guru', scriptName: 'Gurmukhi'},
     50   { scriptCode: 'Hang', scriptName: 'Hangul'},
     51   { scriptCode: 'Hani', scriptName: 'Han'},
     52   { scriptCode: 'Hano', scriptName: 'Hanunoo'},
     53   { scriptCode: 'Hans', scriptName: 'Simplified Han'},
     54   { scriptCode: 'Hant', scriptName: 'Traditional Han'},
     55   { scriptCode: 'Hebr', scriptName: 'Hebrew'},
     56   { scriptCode: 'Hluw', scriptName: 'Anatolian Hieroglyphs'},
     57   { scriptCode: 'Hmng', scriptName: 'Pahawh Hmong'},
     58   { scriptCode: 'Hung', scriptName: 'Old Hungarian'},
     59   { scriptCode: 'Inds', scriptName: 'Indus'},
     60   { scriptCode: 'Ital', scriptName: 'Old Italic'},
     61   { scriptCode: 'Java', scriptName: 'Javanese'},
     62   { scriptCode: 'Jpan', scriptName: 'Japanese'},
     63   { scriptCode: 'Jurc', scriptName: 'Jurchen'},
     64   { scriptCode: 'Kali', scriptName: 'Kayah Li'},
     65   { scriptCode: 'Khar', scriptName: 'Kharoshthi'},
     66   { scriptCode: 'Khmr', scriptName: 'Khmer'},
     67   { scriptCode: 'Khoj', scriptName: 'Khojki'},
     68   { scriptCode: 'Knda', scriptName: 'Kannada'},
     69   { scriptCode: 'Kpel', scriptName: 'Kpelle'},
     70   { scriptCode: 'Kthi', scriptName: 'Kaithi'},
     71   { scriptCode: 'Lana', scriptName: 'Lanna'},
     72   { scriptCode: 'Laoo', scriptName: 'Lao'},
     73   { scriptCode: 'Latf', scriptName: 'Fraktur Latin'},
     74   { scriptCode: 'Latg', scriptName: 'Gaelic Latin'},
     75   { scriptCode: 'Latn', scriptName: 'Latin'},
     76   { scriptCode: 'Lepc', scriptName: 'Lepcha'},
     77   { scriptCode: 'Limb', scriptName: 'Limbu'},
     78   { scriptCode: 'Lina', scriptName: 'Linear A'},
     79   { scriptCode: 'Linb', scriptName: 'Linear B'},
     80   { scriptCode: 'Lisu', scriptName: 'Fraser'},
     81   { scriptCode: 'Loma', scriptName: 'Loma'},
     82   { scriptCode: 'Lyci', scriptName: 'Lycian'},
     83   { scriptCode: 'Lydi', scriptName: 'Lydian'},
     84   { scriptCode: 'Mand', scriptName: 'Mandaean'},
     85   { scriptCode: 'Mani', scriptName: 'Manichaean'},
     86   { scriptCode: 'Maya', scriptName: 'Mayan hieroglyphs'},
     87   { scriptCode: 'Mend', scriptName: 'Mende'},
     88   { scriptCode: 'Merc', scriptName: 'Meroitic Cursive'},
     89   { scriptCode: 'Mero', scriptName: 'Meroitic'},
     90   { scriptCode: 'Mlym', scriptName: 'Malayalam'},
     91   { scriptCode: 'Mong', scriptName: 'Mongolian'},
     92   { scriptCode: 'Moon', scriptName: 'Moon'},
     93   { scriptCode: 'Mroo', scriptName: 'Mro'},
     94   { scriptCode: 'Mtei', scriptName: 'Meitei Mayek'},
     95   { scriptCode: 'Mymr', scriptName: 'Myanmar'},
     96   { scriptCode: 'Narb', scriptName: 'Old North Arabian'},
     97   { scriptCode: 'Nbat', scriptName: 'Nabataean'},
     98   { scriptCode: 'Nkgb', scriptName: 'Naxi Geba'},
     99   { scriptCode: 'Nkoo', scriptName: 'NKo'},
    100   { scriptCode: 'Nshu', scriptName: 'Nshu'},
    101   { scriptCode: 'Ogam', scriptName: 'Ogham'},
    102   { scriptCode: 'Olck', scriptName: 'Ol Chiki'},
    103   { scriptCode: 'Orkh', scriptName: 'Orkhon'},
    104   { scriptCode: 'Orya', scriptName: 'Oriya'},
    105   { scriptCode: 'Osma', scriptName: 'Osmanya'},
    106   { scriptCode: 'Palm', scriptName: 'Palmyrene'},
    107   { scriptCode: 'Perm', scriptName: 'Old Permic'},
    108   { scriptCode: 'Phag', scriptName: 'Phags-pa'},
    109   { scriptCode: 'Phli', scriptName: 'Inscriptional Pahlavi'},
    110   { scriptCode: 'Phlp', scriptName: 'Psalter Pahlavi'},
    111   { scriptCode: 'Phlv', scriptName: 'Book Pahlavi'},
    112   { scriptCode: 'Phnx', scriptName: 'Phoenician'},
    113   { scriptCode: 'Plrd', scriptName: 'Pollard Phonetic'},
    114   { scriptCode: 'Prti', scriptName: 'Inscriptional Parthian'},
    115   { scriptCode: 'Rjng', scriptName: 'Rejang'},
    116   { scriptCode: 'Roro', scriptName: 'Rongorongo'},
    117   { scriptCode: 'Runr', scriptName: 'Runic'},
    118   { scriptCode: 'Samr', scriptName: 'Samaritan'},
    119   { scriptCode: 'Sara', scriptName: 'Sarati'},
    120   { scriptCode: 'Sarb', scriptName: 'Old South Arabian'},
    121   { scriptCode: 'Saur', scriptName: 'Saurashtra'},
    122   { scriptCode: 'Sgnw', scriptName: 'SignWriting'},
    123   { scriptCode: 'Shaw', scriptName: 'Shavian'},
    124   { scriptCode: 'Shrd', scriptName: 'Sharada'},
    125   { scriptCode: 'Sind', scriptName: 'Khudawadi'},
    126   { scriptCode: 'Sinh', scriptName: 'Sinhala'},
    127   { scriptCode: 'Sora', scriptName: 'Sora Sompeng'},
    128   { scriptCode: 'Sund', scriptName: 'Sundanese'},
    129   { scriptCode: 'Sylo', scriptName: 'Syloti Nagri'},
    130   { scriptCode: 'Syrc', scriptName: 'Syriac'},
    131   { scriptCode: 'Syre', scriptName: 'Estrangelo Syriac'},
    132   { scriptCode: 'Syrj', scriptName: 'Western Syriac'},
    133   { scriptCode: 'Syrn', scriptName: 'Eastern Syriac'},
    134   { scriptCode: 'Tagb', scriptName: 'Tagbanwa'},
    135   { scriptCode: 'Takr', scriptName: 'Takri'},
    136   { scriptCode: 'Tale', scriptName: 'Tai Le'},
    137   { scriptCode: 'Talu', scriptName: 'New Tai Lue'},
    138   { scriptCode: 'Taml', scriptName: 'Tamil'},
    139   { scriptCode: 'Tang', scriptName: 'Tangut'},
    140   { scriptCode: 'Tavt', scriptName: 'Tai Viet'},
    141   { scriptCode: 'Telu', scriptName: 'Telugu'},
    142   { scriptCode: 'Teng', scriptName: 'Tengwar'},
    143   { scriptCode: 'Tfng', scriptName: 'Tifinagh'},
    144   { scriptCode: 'Tglg', scriptName: 'Tagalog'},
    145   { scriptCode: 'Thaa', scriptName: 'Thaana'},
    146   { scriptCode: 'Thai', scriptName: 'Thai'},
    147   { scriptCode: 'Tibt', scriptName: 'Tibetan'},
    148   { scriptCode: 'Tirh', scriptName: 'Tirhuta'},
    149   { scriptCode: 'Ugar', scriptName: 'Ugaritic'},
    150   { scriptCode: 'Vaii', scriptName: 'Vai'},
    151   { scriptCode: 'Visp', scriptName: 'Visible Speech'},
    152   { scriptCode: 'Wara', scriptName: 'Varang Kshiti'},
    153   { scriptCode: 'Wole', scriptName: 'Woleai'},
    154   { scriptCode: 'Xpeo', scriptName: 'Old Persian'},
    155   { scriptCode: 'Xsux', scriptName: 'Sumero-Akkadian Cuneiform'},
    156   { scriptCode: 'Yiii', scriptName: 'Yi'},
    157   { scriptCode: 'Zmth', scriptName: 'Mathematical Notation'},
    158   { scriptCode: 'Zsym', scriptName: 'Symbols'}
    159 ];
    160 
    161 // The generic font families supported by the Font Settings Extension API.
    162 var families =
    163     ["standard", "sansserif", "serif", "fixed", "cursive", "fantasy"];
    164 
    165 // Mapping between font list ids and the generic family setting they
    166 // represent.
    167 var fontPickers = [
    168   { fontList: 'standardFontList', name: 'standard' },
    169   { fontList: 'serifFontList', name: 'serif' },
    170   { fontList: 'sansSerifFontList', name: 'sansserif' },
    171   { fontList: 'fixedFontList', name: 'fixed' }
    172 ];
    173 
    174 // Ids of elements to contain the sample text.
    175 var sampleTextDivIds = [
    176   'standardFontSample',
    177   'serifFontSample',
    178   'sansSerifFontSample',
    179   'fixedFontSample',
    180   'minFontSample'
    181 ];
    182 
    183 // Sample texts.
    184 var defaultSampleText = 'The quick brown fox jumps over the lazy dog.';
    185 var scriptSpecificSampleText = {
    186   // "Cyrllic script".
    187   'Cyrl': '',
    188   'Hang': '         .',
    189   'Hans': '',
    190   'Hant': '',
    191   'Jpan': '',
    192   // "Khmer language".
    193   'Khmr': '\u1797\u17B6\u179F\u17B6\u1781\u17D2\u1798\u17C2\u179A',
    194 };
    195 
    196 // Definition for ScriptList.
    197 cr.define('fontSettings.ui', function() {
    198   const List = cr.ui.List;
    199   const ListItem = cr.ui.ListItem;
    200   const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
    201 
    202   function ScriptListItem(info) {
    203     var el = cr.doc.createElement('li');
    204     el.__proto__ = ScriptListItem.prototype;
    205     el.info_ = info;
    206     el.decorate();
    207     return el;
    208   };
    209 
    210   ScriptListItem.prototype = {
    211     __proto__: ListItem.prototype,
    212 
    213     decorate: function() {
    214       this.textContent = this.info_.scriptName;
    215       if (this.info_.scriptCode == 'Zyyy') {
    216         this.style.marginBottom = '1em';
    217       }
    218     }
    219   };
    220 
    221   var ScriptList = cr.ui.define('list');
    222   ScriptList.prototype = {
    223     __proto__: List.prototype,
    224 
    225     decorate: function() {
    226       List.prototype.decorate.call(this);
    227       var sm = new ListSingleSelectionModel();
    228       this.selectionModel = sm;
    229       this.autoExpands = true;
    230       this.dataModel = new cr.ui.ArrayDataModel(scripts);
    231       this.style.height = '75vh';
    232     },
    233 
    234     createItem: function(info) {
    235       return new ScriptListItem(info);
    236     }
    237   };
    238 
    239   return {
    240     ScriptList: ScriptList,
    241     ScriptListItem: ScriptListItem
    242   };
    243 });
    244 
    245 function getSelectedScript() {
    246   var scriptList = document.getElementById('scriptList');
    247   return scriptList.selectedItem.scriptCode;
    248 }
    249 
    250 function getSelectedFont(fontList) {
    251   return fontList.options[fontList.selectedIndex].value;
    252 }
    253 
    254 // Populates the font lists with the list of system fonts from |fonts|.
    255 function populateLists(fonts) {
    256   for (var i = 0; i < fontPickers.length; i++) {
    257     var list = document.getElementById(fontPickers[i].fontList);
    258 
    259     // Add special item to indicate fallback to the non-per-script
    260     // font setting. The Font Settings API uses the empty string to indicate
    261     // fallback.
    262     var defaultItem = document.createElement('option');
    263     defaultItem.value = '';
    264     defaultItem.text = '(Use default)';
    265     list.add(defaultItem);
    266 
    267     for (var j = 0; j < fonts.length; j++) {
    268       var item = document.createElement('option');
    269       item.value = fonts[j].fontId;
    270       item.text = fonts[j].displayName;
    271       list.add(item);
    272     }
    273   }
    274 
    275   updateFontListsForScript();
    276 }
    277 
    278 // Returns a function that updates the font setting for |genericFamily|
    279 // to match the selected value in |fontList|. It can be used as an event
    280 // handler for selection changes in |fontList|.
    281 function getFontChangeHandler(fontList, genericFamily) {
    282   return function() {
    283     var script = getSelectedScript();
    284     var font = getSelectedFont(fontList);
    285 
    286     var details = {};
    287     details.genericFamily = genericFamily;
    288     details.fontId = font;
    289     details.script = script;
    290 
    291     chrome.fontSettings.setFont(details);
    292   };
    293 }
    294 
    295 // Sets the selected value of |fontList| to |fontId|.
    296 function setSelectedFont(fontList, fontId) {
    297   var script = getSelectedScript();
    298   var i;
    299   for (i = 0; i < fontList.length; i++) {
    300     if (fontId == fontList.options[i].value) {
    301       fontList.selectedIndex = i;
    302       break;
    303     }
    304   }
    305   if (i == fontList.length) {
    306     console.warn("font '" + fontId + "' for " + fontList.id + ' for ' +
    307         script + ' is not on the system');
    308   }
    309 }
    310 
    311 // Returns a callback function that sets the selected value of |list| to the
    312 // font returned from |chrome.fontSettings.getFont|.
    313 function getFontHandler(list) {
    314   return function(details) {
    315     setSelectedFont(list, details.fontId);
    316     list.disabled = !isControllableLevel(details.levelOfControl);
    317   };
    318 }
    319 
    320 // Called when the script list selection changes. Sets the selected value of
    321 // each font list to the current font setting, and updates the samples' lang
    322 // so that they are shown in the current font setting.
    323 function updateFontListsForScript() {
    324   var script = getSelectedScript();
    325 
    326   for (var i = 0; i < fontPickers.length; i++) {
    327     var list = document.getElementById(fontPickers[i].fontList);
    328     var family = fontPickers[i].name;
    329 
    330     var details = {};
    331     details.genericFamily = family;
    332     details.script = script;
    333     chrome.fontSettings.getFont(details, getFontHandler(list));
    334   }
    335 
    336   if (typeof(scriptSpecificSampleText[script]) != 'undefined')
    337     sample = scriptSpecificSampleText[script];
    338   else
    339     sample = defaultSampleText;
    340   for (var i = 0; i < sampleTextDivIds.length; i++) {
    341     var sampleTextDiv = document.getElementById(sampleTextDivIds[i]);
    342     // For font selection it's the script code that matters, not language, so
    343     // just use en for lang.
    344     sampleTextDiv.lang = 'en-' + script;
    345     sampleTextDiv.innerText = sample;
    346   }
    347 }
    348 
    349 // Returns a function to be called when the user changes the font size
    350 // input element |elem|. The function calls the Font Settings Extension API
    351 // function |setter| to commit the change.
    352 function getFontSizeChangedFunc(elem, setter) {
    353   return function() {
    354     var pixelSize = parseInt(elem.value);
    355     if (!isNaN(pixelSize)) {
    356       setter({ pixelSize: pixelSize });
    357     }
    358   }
    359 }
    360 
    361 function isControllableLevel(levelOfControl) {
    362   return levelOfControl == 'controllable_by_this_extension' ||
    363       levelOfControl == 'controlled_by_this_extension';
    364 }
    365 
    366 // Returns a function to be used as a listener for font size setting changed
    367 // events from the Font Settings Extension API. The function updates the input
    368 // element |elem| and the elements in |sampleTexts| to reflect the change.
    369 function getFontSizeChangedOnBrowserFunc(elem, sampleTexts) {
    370   return function(details) {
    371     var size = details.pixelSize.toString();
    372     elem.value = size;
    373     elem.disabled = !isControllableLevel(details.levelOfControl);
    374     for (var i = 0; i < sampleTexts.length; i++)
    375       document.getElementById(sampleTexts[i]).style.fontSize = size + 'px';
    376   }
    377 }
    378 
    379 // Maps the HTML <input> element with |id| to the extension API accessor
    380 // functions |getter| and |setter| for a setting and onChange event |apiEvent|
    381 // for the setting. Also, maps the element ids in |sampleTexts| to this setting.
    382 function initFontSizePref(id, sampleTexts, getter, setter, apiEvent) {
    383   var elem = document.getElementById(id);
    384   getter({}, function(details) {
    385     var size = details.pixelSize.toString();
    386     elem.value = size;
    387     elem.disabled = !isControllableLevel(details.levelOfControl);
    388     for (var i = 0; i < sampleTexts.length; i++)
    389       document.getElementById(sampleTexts[i]).style.fontSize = size + 'px';
    390   });
    391   elem.addEventListener('change', getFontSizeChangedFunc(elem, setter));
    392   apiEvent.addListener(getFontSizeChangedOnBrowserFunc(elem, sampleTexts));
    393 }
    394 
    395 function clearSettingsForScript(script) {
    396   for (var i = 0; i < families.length; i++) {
    397     chrome.fontSettings.clearFont({
    398       script: script,
    399       genericFamily: families[i]
    400     });
    401   }
    402 }
    403 
    404 function clearAllSettings() {
    405   for (var i = 0; i < scripts.length; i++)
    406     clearSettingsForScript(scripts[i].scriptCode);
    407 
    408   chrome.fontSettings.clearDefaultFixedFontSize();
    409   chrome.fontSettings.clearDefaultFontSize();
    410   chrome.fontSettings.clearMinimumFontSize();
    411 }
    412 
    413 function closeOverlay() {
    414   $('overlay-container').hidden = true;
    415 }
    416 
    417 function initResetButtons() {
    418   var overlay = $('overlay-container');
    419   cr.ui.overlay.globalInitialization();
    420   cr.ui.overlay.setupOverlay(overlay);
    421   overlay.addEventListener('cancelOverlay', closeOverlay);
    422 
    423   $('reset-this-script-button').onclick = function(event) {
    424     var scriptName = $('scriptList').selectedItem.scriptName;
    425     $('reset-this-script-overlay-dialog-content').innerText =
    426         'Are you sure you want to reset settings for ' + scriptName +
    427         ' script?';
    428 
    429     $('overlay-container').hidden = false;
    430     $('reset-this-script-overlay-dialog').hidden = false;
    431     $('reset-all-scripts-overlay-dialog').hidden = true;
    432   }
    433   $('reset-this-script-ok').onclick = function(event) {
    434     clearSettingsForScript(getSelectedScript());
    435     closeOverlay();
    436   };
    437   $('reset-this-script-cancel').onclick = closeOverlay;
    438 
    439   $('reset-all-button').onclick = function(event) {
    440     $('overlay-container').hidden = false;
    441     $('reset-all-scripts-overlay-dialog').hidden = false;
    442     $('reset-this-script-overlay-dialog').hidden = true;
    443   }
    444   $('reset-all-ok').onclick = function(event) {
    445     clearAllSettings();
    446     closeOverlay();
    447   }
    448   $('reset-all-cancel').onclick = closeOverlay;
    449 }
    450 
    451 function init() {
    452   var scriptList = document.getElementById('scriptList');
    453   fontSettings.ui.ScriptList.decorate(scriptList);
    454   scriptList.selectionModel.selectedIndex = 0;
    455   scriptList.selectionModel.addEventListener('change',
    456                                              updateFontListsForScript);
    457 
    458   // Populate the font lists.
    459   chrome.fontSettings.getFontList(populateLists);
    460 
    461   // Add change handlers to the font lists.
    462   for (var i = 0; i < fontPickers.length; i++) {
    463     var list = document.getElementById(fontPickers[i].fontList);
    464     var handler = getFontChangeHandler(list, fontPickers[i].name);
    465     list.addEventListener('change', handler);
    466   }
    467 
    468   chrome.fontSettings.onFontChanged.addListener(
    469       updateFontListsForScript);
    470 
    471   initFontSizePref(
    472       'defaultFontSizeRocker',
    473       ['standardFontSample', 'serifFontSample', 'sansSerifFontSample'],
    474       chrome.fontSettings.getDefaultFontSize,
    475       chrome.fontSettings.setDefaultFontSize,
    476       chrome.fontSettings.onDefaultFontSizeChanged);
    477   initFontSizePref(
    478       'defaultFontSizeRange',
    479       ['standardFontSample', 'serifFontSample', 'sansSerifFontSample'],
    480       chrome.fontSettings.getDefaultFontSize,
    481       chrome.fontSettings.setDefaultFontSize,
    482       chrome.fontSettings.onDefaultFontSizeChanged);
    483   initFontSizePref(
    484       'defaultFixedFontSizeRocker',
    485       ['fixedFontSample'],
    486       chrome.fontSettings.getDefaultFixedFontSize,
    487       chrome.fontSettings.setDefaultFixedFontSize,
    488       chrome.fontSettings.onDefaultFixedFontSizeChanged);
    489   initFontSizePref(
    490       'defaultFixedFontSizeRange',
    491       ['fixedFontSample'],
    492       chrome.fontSettings.getDefaultFixedFontSize,
    493       chrome.fontSettings.setDefaultFixedFontSize,
    494       chrome.fontSettings.onDefaultFixedFontSizeChanged);
    495   initFontSizePref(
    496       'minFontSizeRocker',
    497       ['minFontSample'],
    498       chrome.fontSettings.getMinimumFontSize,
    499       chrome.fontSettings.setMinimumFontSize,
    500       chrome.fontSettings.onMinimumFontSizeChanged);
    501   initFontSizePref(
    502       'minFontSizeRange',
    503       ['minFontSample'],
    504       chrome.fontSettings.getMinimumFontSize,
    505       chrome.fontSettings.setMinimumFontSize,
    506       chrome.fontSettings.onMinimumFontSizeChanged);
    507 
    508   initResetButtons();
    509 }
    510 
    511 document.addEventListener('DOMContentLoaded', init);
    512