Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: chrome/common/extensions/docs/examples/api/fontSettings/options.js

Issue 23434003: UI refresh of Advanced Font Settings Extension (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review comments Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // The scripts supported by the Font Settings Extension API. 5 /**
6 var scripts = [ 6 * @fileoverview The Advanced Font Settings Extension implementation.
7 { scriptCode: 'Zyyy', scriptName: 'Default'}, 7 */
8
9 function $(id) {
10 return document.getElementById(id);
11 }
12
13 var advancedFonts = {};
yoshiki 2013/08/28 08:58:44 Please add "@namespace" annotation. /** * @names
falken 2013/08/29 09:35:44 Done.
14
15 /**
16 * The ICU script code for the Common, or global, script, which is used as the
17 * fallback when the script is undeclared.
18 * @const
19 */
20 advancedFonts.COMMON_SCRIPT = 'Zyyy';
21
22 /**
23 * The scripts supported by the Font Settings Extension API.
24 * @const
25 */
26 advancedFonts.scripts = [
27 { scriptCode: advancedFonts.COMMON_SCRIPT, scriptName: 'Default'},
8 { scriptCode: 'Afak', scriptName: 'Afaka'}, 28 { scriptCode: 'Afak', scriptName: 'Afaka'},
9 { scriptCode: 'Arab', scriptName: 'Arabic'}, 29 { scriptCode: 'Arab', scriptName: 'Arabic'},
10 { scriptCode: 'Armi', scriptName: 'Imperial Aramaic'}, 30 { scriptCode: 'Armi', scriptName: 'Imperial Aramaic'},
11 { scriptCode: 'Armn', scriptName: 'Armenian'}, 31 { scriptCode: 'Armn', scriptName: 'Armenian'},
12 { scriptCode: 'Avst', scriptName: 'Avestan'}, 32 { scriptCode: 'Avst', scriptName: 'Avestan'},
13 { scriptCode: 'Bali', scriptName: 'Balinese'}, 33 { scriptCode: 'Bali', scriptName: 'Balinese'},
14 { scriptCode: 'Bamu', scriptName: 'Bamum'}, 34 { scriptCode: 'Bamu', scriptName: 'Bamum'},
15 { scriptCode: 'Bass', scriptName: 'Bassa Vah'}, 35 { scriptCode: 'Bass', scriptName: 'Bassa Vah'},
16 { scriptCode: 'Batk', scriptName: 'Batak'}, 36 { scriptCode: 'Batk', scriptName: 'Batak'},
17 { scriptCode: 'Beng', scriptName: 'Bengali'}, 37 { scriptCode: 'Beng', scriptName: 'Bengali'},
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 { scriptCode: 'Visp', scriptName: 'Visible Speech'}, 171 { scriptCode: 'Visp', scriptName: 'Visible Speech'},
152 { scriptCode: 'Wara', scriptName: 'Varang Kshiti'}, 172 { scriptCode: 'Wara', scriptName: 'Varang Kshiti'},
153 { scriptCode: 'Wole', scriptName: 'Woleai'}, 173 { scriptCode: 'Wole', scriptName: 'Woleai'},
154 { scriptCode: 'Xpeo', scriptName: 'Old Persian'}, 174 { scriptCode: 'Xpeo', scriptName: 'Old Persian'},
155 { scriptCode: 'Xsux', scriptName: 'Sumero-Akkadian Cuneiform'}, 175 { scriptCode: 'Xsux', scriptName: 'Sumero-Akkadian Cuneiform'},
156 { scriptCode: 'Yiii', scriptName: 'Yi'}, 176 { scriptCode: 'Yiii', scriptName: 'Yi'},
157 { scriptCode: 'Zmth', scriptName: 'Mathematical Notation'}, 177 { scriptCode: 'Zmth', scriptName: 'Mathematical Notation'},
158 { scriptCode: 'Zsym', scriptName: 'Symbols'} 178 { scriptCode: 'Zsym', scriptName: 'Symbols'}
159 ]; 179 ];
160 180
161 // The generic font families supported by the Font Settings Extension API. 181 /**
162 var families = 182 * The generic font families supported by the Font Settings Extension API.
163 ["standard", "sansserif", "serif", "fixed", "cursive", "fantasy"]; 183 * @const
184 */
185 advancedFonts.FAMILIES =
186 ['standard', 'sansserif', 'serif', 'fixed', 'cursive', 'fantasy'];
164 187
165 // Mapping between font list ids and the generic family setting they 188 /**
166 // represent. 189 * Sample texts.
167 var fontPickers = [ 190 * @const
168 { fontList: 'standardFontList', name: 'standard' }, 191 */
169 { fontList: 'serifFontList', name: 'serif' }, 192 advancedFonts.SAMPLE_TEXTS = {
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". 193 // "Cyrllic script".
187 'Cyrl': 'Кириллица', 194 'Cyrl': 'Кириллица',
188 'Hang': '정 참판 양반댁 규수 큰 교자 타고 혼례 치른 날.', 195 'Hang': '정 참판 양반댁 규수 큰 교자 타고 혼례 치른 날.',
189 'Hans': '床前明月光,疑是地上霜。举头望明月,低头思故乡。', 196 'Hans': '床前明月光,疑是地上霜。举头望明月,低头思故乡。',
190 'Hant': '床前明月光,疑是地上霜。舉頭望明月,低頭思故鄉。', 197 'Hant': '床前明月光,疑是地上霜。舉頭望明月,低頭思故鄉。',
191 'Jpan': '吾輩は猫である。名前はまだ無い。', 198 'Jpan': '吾輩は猫である。名前はまだ無い。',
192 // "Khmer language". 199 // "Khmer language".
193 'Khmr': '\u1797\u17B6\u179F\u17B6\u1781\u17D2\u1798\u17C2\u179A', 200 'Khmr': '\u1797\u17B6\u179F\u17B6\u1781\u17D2\u1798\u17C2\u179A',
201 'Zyyy': 'The quick brown fox jumps over the lazy dog.'
hirono 2013/08/28 08:47:30 Could you remove the quotations for keys? The styl
falken 2013/08/29 09:35:44 Done.
194 }; 202 };
195 203
196 // Definition for ScriptList. 204 /**
197 cr.define('fontSettings.ui', function() { 205 * Controller of pending changes.
198 const List = cr.ui.List; 206 * @const
199 const ListItem = cr.ui.ListItem; 207 */
200 const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; 208 advancedFonts.pendingChanges = new PendingChanges();
201 209
202 function ScriptListItem(info) { 210 /**
203 var el = cr.doc.createElement('li'); 211 * Map from |genericFamily| to UI controls and data for its font setting.
204 el.__proto__ = ScriptListItem.prototype; 212 */
205 el.info_ = info; 213 advancedFonts.fontSettings = null;
206 el.decorate(); 214
207 return el; 215 /**
216 * Map from |fontSizeKey| to UI contols and data for its font size setting.
217 */
218 advancedFonts.fontSizeSettings = null;
219
220 /**
221 * @return {function} A function of form function(x) which calls
222 * callback(x, y, z) where |y| and |z| are fixed to |font| and |controllable|,
223 * respectively.
224 */
225 advancedFonts.getBoundCallback = function(callback, font, controllable) {
hirono 2013/08/28 08:47:30 It seems that function.bind can be used instead of
falken 2013/08/29 09:35:44 I think I can't use that since the second and thir
226 return function(effectiveFont) {
227 callback(effectiveFont, font, controllable)
208 }; 228 };
209 229 }
210 ScriptListItem.prototype = { 230
211 __proto__: ListItem.prototype, 231 /**
212 232 * Gets the font size used for |fontSizeKey|, including pending changes. Calls
213 decorate: function() { 233 * |callback| with the result.
214 this.textContent = this.info_.scriptName; 234 *
215 if (this.info_.scriptCode == 'Zyyy') { 235 * @param {string} fontSizeKey The font size setting key. See
216 this.style.marginBottom = '1em'; 236 * PendingChanges.getFontSize().
237 * @param {function(number, boolean)} callback The callback of form
238 * function(size, controllable). |size| is the effective setting,
239 * |controllable| is whether the setting can be set.
240 */
241 advancedFonts.getEffectiveFontSize = function(fontSizeKey, callback) {
242 advancedFonts.fontSizeSettings[fontSizeKey].getter({}, function(details) {
243 var controllable = advancedFonts.isControllableLevel(
244 details.levelOfControl);
245 var size = details.pixelSize;
246 var pendingFontSize = advancedFonts.pendingChanges.getFontSize(fontSizeKey);
247 // If the setting is not controllable, we can have no pending change.
248 if (!controllable) {
249 if (pendingFontSize != null) {
250 advancedFonts.pendingChanges.setFontSize(fontSizeKey, null);
251 advancedFonts.refresh();
252 pendingFontSize = null;
217 } 253 }
218 } 254 }
255
256 // If we have a pending change, it overrides the current setting.
257 if (pendingFontSize != null)
258 size = pendingFontSize;
259 callback(size, controllable);
260 });
261 }
262
263 /**
264 * Gets the font used for |script| and |genericFamily|, including pending
265 * changes. Calls |callback| with the result.
266 *
267 * @param {string} script The script code.
268 * @param {string} genericFamily The generic family.
269 * @param {function(string, string, boolean)} callback The callback of form
270 * function(effectiveFont, font, controllable). |effectiveFont| is the font
271 * used taking fallback into consideration, |font| is the actual setting
272 * (pending or not), |controllable| is whether the setting can be set.
273 */
274 advancedFonts.getEffectiveFont = function(script, genericFamily, callback) {
275 var pendingChanges = advancedFonts.pendingChanges;
276 var details = { script: script, genericFamily: genericFamily };
277 var pendingFont =
278 pendingChanges.getFont(details.script, details.genericFamily);
279 chrome.fontSettings.getFont(details, function(result) {
280 var setting = {};
281 setting.font = result.fontId;
282 setting.controllable =
283 advancedFonts.isControllableLevel(result.levelOfControl);
284 // If the setting is not controllable, we can have no pending change.
285 if (!setting.controllable) {
286 pendingFont = null;
287 if (pendingChanges.getFont[script])
288 pendingChanges.setFont([script][genericFamily], null);
289 refresh();
290 }
291
292 // If we have a pending change, it overrides the current setting.
293 if (pendingFont != null)
294 setting.font = pendingFont;
295
296 // If we have a font, we're done.
297 if (setting.font) {
298 callback(setting.font, setting.font, setting.controllable);
299 return;
300 }
301
302 // If we're still here, we have to fallback to common script, unless this
303 // already is common script.
304 if (script == advancedFonts.COMMON_SCRIPT) {
305 callback('', '', setting.controllable);
306 return;
307 }
308 advancedFonts.getEffectiveFont(
309 advancedFonts.COMMON_SCRIPT,
310 genericFamily,
311 advancedFonts.getBoundCallback(
312 callback, setting.font, setting.controllable));
313 });
314 }
315
316 /**
317 * Returns a function that refreshes the UI controls related to a font setting.
318 *
319 * @param {HTMLSelectElement} list The <select> containing the list of fonts.
320 * @param {array} samples An array of HTMLElement objects with sample text that
321 * are rendered using this font setting.
322 * @return {function(string, string, boolean)} A function of form
323 * function(effectiveFont, font, controllable) that refreshes the UI
324 * controls for this font setting. |effectiveFont| is the font used
325 * including fallback, |font| is the value of the font setting (including
326 * pending changes), |controllable| is whether the setting can be
327 * controlled.
328 */
329 advancedFonts.getRefreshFontFunction = function(list, samples) {
330 return function(effectiveFont, font, controllable) {
331 for (var i = 0; i < samples.length; ++i)
332 samples[i].style.fontFamily = effectiveFont;
333 advancedFonts.setSelectedFont(list, font);
334 list.disabled = !controllable;
335 }
336 }
337
338 /**
339 * Returns a function that refreshes the UI controls related to a font size
340 * setting.
341 *
342 * @param {string} fontSizeKey The font size setting key. See
343 * PendingChanges.getFontSize().
344 * @return {function(number, boolean)} A function of form
345 * function(size, controllable) that refreshes the UI controls for this
346 * font size setting. |size| is the value of the font size setting
347 * (including pending changes), |controllable| is whether the setting can be
348 * controlled.
349 */
350 advancedFonts.getRefreshFontSizeFunction = function(fontSizeKey) {
351 var fontSizeSetting = advancedFonts.fontSizeSettings[fontSizeKey];
352 return function(size, controllable) {
353 fontSizeSetting.label.innerText = 'Size: ' + size + 'px';
354 advancedFonts.setFontSizeSlider(fontSizeSetting.slider, size, controllable);
355 for (var i = 0; i < fontSizeSetting.samples.length; ++i)
356 fontSizeSetting.samples[i].style.fontSize = size + 'px';
219 }; 357 };
220 358 }
221 var ScriptList = cr.ui.define('list'); 359
222 ScriptList.prototype = { 360 /**
223 __proto__: List.prototype, 361 * Refreshes all UI controls to reflect the current settings, including pending
224 362 * changes.
225 decorate: function() { 363 */
226 List.prototype.decorate.call(this); 364 advancedFonts.refresh = function() {
227 var sm = new ListSingleSelectionModel(); 365 var script = advancedFonts.getSelectedScript();
228 this.selectionModel = sm; 366 var sample;
229 this.autoExpands = true; 367 if (advancedFonts.SAMPLE_TEXTS[script])
230 this.dataModel = new cr.ui.ArrayDataModel(scripts); 368 sample = advancedFonts.SAMPLE_TEXTS[script];
231 this.style.height = '75vh'; 369 else
232 }, 370 sample = advancedFonts.SAMPLE_TEXTS[advancedFonts.COMMON_SCRIPT];
233 371 var sampleTexts = document.querySelectorAll('.sample-text-span');
234 createItem: function(info) { 372 for (var i = 0; i < sampleTexts.length; i++)
235 return new ScriptListItem(info); 373 sampleTexts[i].textContent = sample;
236 } 374
237 }; 375 var callback;
238 376 for (var genericFamily in advancedFonts.fontSettings) {
239 return { 377 var setting = advancedFonts.fontSettings[genericFamily];
240 ScriptList: ScriptList, 378 callback = advancedFonts.getRefreshFontFunction(setting.fontList,
241 ScriptListItem: ScriptListItem 379 setting.samples);
242 }; 380 advancedFonts.getEffectiveFont(script, genericFamily, callback);
243 }); 381 }
244 382
245 function getSelectedScript() { 383 for (var fontSizeKey in advancedFonts.fontSizeSettings) {
246 var scriptList = document.getElementById('scriptList'); 384 callback = advancedFonts.getRefreshFontSizeFunction(fontSizeKey);
247 return scriptList.selectedItem.scriptCode; 385 advancedFonts.getEffectiveFontSize(fontSizeKey, callback);
248 } 386 }
249 387
250 function getSelectedFont(fontList) { 388 $('apply-settings').disabled = advancedFonts.pendingChanges.isEmpty();
389 }
390
391 /**
392 * @return {string} The currently selected script code.
393 */
394 advancedFonts.getSelectedScript = function() {
395 var scriptList = $('scriptList');
396 return scriptList.options[scriptList.selectedIndex].value;
397 }
398
399 /**
400 * @param {HTMLSelectElement} fontList The <select> containing a list of fonts.
401 * @return {string} The currently selected value of |fontList|.
402 */
403 advancedFonts.getSelectedFont = function(fontList) {
251 return fontList.options[fontList.selectedIndex].value; 404 return fontList.options[fontList.selectedIndex].value;
252 } 405 }
253 406
254 // Populates the font lists with the list of system fonts from |fonts|. 407 /**
255 function populateLists(fonts) { 408 * Populates the font lists.
256 for (var i = 0; i < fontPickers.length; i++) { 409 * @param {array} fonts The list of fonts on the system.
257 var list = document.getElementById(fontPickers[i].fontList); 410 */
258 411 advancedFonts.populateFontLists = function(fonts) {
259 // Add special item to indicate fallback to the non-per-script 412 for (var genericFamily in advancedFonts.fontSettings) {
413 var list = advancedFonts.fontSettings[genericFamily].fontList;
414
415 // Add a special item to indicate fallback to the non-per-script
260 // font setting. The Font Settings API uses the empty string to indicate 416 // font setting. The Font Settings API uses the empty string to indicate
261 // fallback. 417 // fallback.
262 var defaultItem = document.createElement('option'); 418 var defaultItem = document.createElement('option');
263 defaultItem.value = ''; 419 defaultItem.value = '';
264 defaultItem.text = '(Use default)'; 420 defaultItem.text = '(Use default)';
265 list.add(defaultItem); 421 list.add(defaultItem);
266 422
267 for (var j = 0; j < fonts.length; j++) { 423 for (var i = 0; i < fonts.length; ++i) {
268 var item = document.createElement('option'); 424 var item = document.createElement('option');
269 item.value = fonts[j].fontId; 425 item.value = fonts[i].fontId;
270 item.text = fonts[j].displayName; 426 item.text = fonts[i].displayName;
271 list.add(item); 427 list.add(item);
272 } 428 }
273 } 429 }
274 430 advancedFonts.refresh();
275 updateFontListsForScript();
276 } 431 }
277 432
278 // Returns a function that updates the font setting for |genericFamily| 433 /**
279 // to match the selected value in |fontList|. It can be used as an event 434 * @param {HTMLSelectElement} fontList The <select> containing a list of fonts.
280 // handler for selection changes in |fontList|. 435 * @param {string} genericFamily The generic family for the font setting.
281 function getFontChangeHandler(fontList, genericFamily) { 436 * @return {function} A function to be called when the user changes the selected
437 * font in |fontList|. The function updates the pending font change.
438 */
439 advancedFonts.getFontChangeHandler = function(fontList, genericFamily) {
282 return function() { 440 return function() {
283 var script = getSelectedScript(); 441 var script = advancedFonts.getSelectedScript();
284 var font = getSelectedFont(fontList); 442 var font = advancedFonts.getSelectedFont(fontList);
285 443
286 var details = {}; 444 advancedFonts.pendingChanges.setFont(script, genericFamily, font);
287 details.genericFamily = genericFamily; 445 advancedFonts.refresh();
288 details.fontId = font;
289 details.script = script;
290
291 chrome.fontSettings.setFont(details);
292 }; 446 };
293 } 447 }
294 448
295 // Sets the selected value of |fontList| to |fontId|. 449 /**
296 function setSelectedFont(fontList, fontId) { 450 * Sets the selected value of |fontList| to |fontId|.
297 var script = getSelectedScript(); 451 * @param {HTMLSelectElement} fontList The <select> containing a list of fonts.
452 * @param {string} fontId The font to set |fontList|'s selection to.
453 */
454 advancedFonts.setSelectedFont = function(fontList, fontId) {
455 var script = advancedFonts.getSelectedScript();
298 var i; 456 var i;
299 for (i = 0; i < fontList.length; i++) { 457 for (i = 0; i < fontList.length; i++) {
300 if (fontId == fontList.options[i].value) { 458 if (fontId == fontList.options[i].value) {
301 fontList.selectedIndex = i; 459 fontList.selectedIndex = i;
302 break; 460 break;
303 } 461 }
304 } 462 }
305 if (i == fontList.length) { 463 if (i == fontList.length) {
306 console.warn("font '" + fontId + "' for " + fontList.id + ' for ' + 464 console.warn("font '" + fontId + "' for " + fontList.id + ' for ' +
307 script + ' is not on the system'); 465 script + ' is not on the system');
308 } 466 }
309 } 467 }
310 468
311 // Returns a callback function that sets the selected value of |list| to the 469 /**
312 // font returned from |chrome.fontSettings.getFont|. 470 * Return a function that handles changes to the font size slider.
313 function getFontHandler(list) { 471 * @param {string} fontSizeKey The key for font size setting whose slider the
314 return function(details) { 472 * function should handle changed for. See PendingChanges.getFont.
315 setSelectedFont(list, details.fontId); 473 * @return {function(number)} A function to be called when the user changes the
316 list.disabled = !isControllableLevel(details.levelOfControl); 474 * font size slider for |fontSizeKey|. The function sets the pending font
317 }; 475 * size change.
318 } 476 */
319 477 advancedFonts.getFontSizeChangedFunc = function(fontSizeKey) {
320 // Called when the script list selection changes. Sets the selected value of 478 return function(value) {
321 // each font list to the current font setting, and updates the samples' lang 479 var pixelSize = parseInt(value);
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)) { 480 if (!isNaN(pixelSize)) {
356 setter({ pixelSize: pixelSize }); 481 advancedFonts.pendingChanges.setFontSize(fontSizeKey, pixelSize);
482 advancedFonts.refresh();
357 } 483 }
358 } 484 }
359 } 485 }
360 486
361 function isControllableLevel(levelOfControl) { 487 /**
488 * @param {string} levelOfControl The level of control string for a setting,
489 * as returned by the Font Settings Extension API.
490 * @return {boolean} True if |levelOfControl| signifies that the extension can
491 * control the setting; otherwise, returns false.
492 */
493 advancedFonts.isControllableLevel = function(levelOfControl) {
362 return levelOfControl == 'controllable_by_this_extension' || 494 return levelOfControl == 'controllable_by_this_extension' ||
363 levelOfControl == 'controlled_by_this_extension'; 495 levelOfControl == 'controlled_by_this_extension';
364 } 496 }
365 497
366 // Returns a function to be used as a listener for font size setting changed 498 /**
367 // events from the Font Settings Extension API. The function updates the input 499 * Returns a function to be used as a listener for font size setting changed
368 // element |elem| and the elements in |sampleTexts| to reflect the change. 500 * events from the Font Settings Extension API.
369 function getFontSizeChangedOnBrowserFunc(elem, sampleTexts) { 501 * @param {Slider} slider The slider for the font size setting.
502 * @param {HTMLElement} label The element that displays the slider's value.
503 * @param {array} sampleTexts An array of elements containing sample text
504 * which is rendered using this font size setting.
505 * @return {function(object) A function that can listen for font size change
506 * events from the browser and update |slider|, |label|, and |sampleTexts|
507 * to reflect the change.
508 */
509 advancedFonts.getFontSizeChangedOnBrowserFunc =
510 function(slider, label, sampleTexts) {
370 return function(details) { 511 return function(details) {
371 var size = details.pixelSize.toString(); 512 var size = details.pixelSize.toString();
372 elem.value = size; 513 var controllable =
373 elem.disabled = !isControllableLevel(details.levelOfControl); 514 advancedFonts.isControllableLevel(details.levelOfControl);
515 advancedFonts.setFontSizeSlider(slider, size, controllable);
516 label.disabled = !controllable;
374 for (var i = 0; i < sampleTexts.length; i++) 517 for (var i = 0; i < sampleTexts.length; i++)
375 document.getElementById(sampleTexts[i]).style.fontSize = size + 'px'; 518 sampleTexts[i].style.fontSize = size + 'px';
519 label.innerText = 'Size: ' + size + 'px';
376 } 520 }
377 } 521 }
378 522
379 // Maps the HTML <input> element with |id| to the extension API accessor 523 /*
380 // functions |getter| and |setter| for a setting and onChange event |apiEvent| 524 * Updates the specified font size slider's value and enabled property.
381 // for the setting. Also, maps the element ids in |sampleTexts| to this setting. 525 * @param {Slider} slider The slider for a font size setting.
382 function initFontSizePref(id, sampleTexts, getter, setter, apiEvent) { 526 * @param {number} size The value to set the slider to.
383 var elem = document.getElementById(id); 527 * @param {boolean} enabled Whether to enable or disable the slider.
384 getter({}, function(details) { 528 */
385 var size = details.pixelSize.toString(); 529 advancedFonts.setFontSizeSlider = function(slider, size, enabled) {
386 elem.value = size; 530 if (slider.getValue() != size)
387 elem.disabled = !isControllableLevel(details.levelOfControl); 531 slider.setValue(size);
388 for (var i = 0; i < sampleTexts.length; i++) 532 var inputElement = slider.getInput();
389 document.getElementById(sampleTexts[i]).style.fontSize = size + 'px'; 533 if (enabled) {
390 }); 534 inputElement.parentNode.classList.remove('disabled');
391 elem.addEventListener('change', getFontSizeChangedFunc(elem, setter)); 535 inputElement.disabled = false;
392 apiEvent.addListener(getFontSizeChangedOnBrowserFunc(elem, sampleTexts)); 536 } else {
537 inputElement.parentNode.classList.add('disabled');
538 inputElement.disabled = true;
539 }
393 } 540 }
394 541
395 function clearSettingsForScript(script) { 542 /**
396 for (var i = 0; i < families.length; i++) { 543 * Initializes the UI control elements related to the font size setting
544 * |fontSizeKey| and registers listeners for the user adjusting its slider and
545 * the setting changing on the browser-side.
546 * @param {string} fontSizeKey The key for font size setting. See
547 * PendingChanges.getFont().
548 */
549 advancedFonts.initFontSizeSetting = function(fontSizeKey) {
550 var fontSizeSettings = advancedFonts.fontSizeSettings;
551 var setting = fontSizeSettings[fontSizeKey];
552 var label = setting.label;
553 var samples = setting.samples;
554
555 setting.slider = new Slider(
556 setting.sliderContainer,
557 0,
558 setting.minValue,
559 setting.maxValue,
560 advancedFonts.getFontSizeChangedFunc(fontSizeKey)
561 );
562
563 var slider = setting.slider;
564 setting.getter({}, function(details) {
565 var size = details.pixelSize.toString();
566 var controllable = advancedFonts.isControllableLevel(
567 details.levelOfControl);
568 advancedFonts.setFontSizeSlider(slider, size, controllable);
569 for (var i = 0; i < samples.length; i++)
570 samples[i].style.fontSize = size + 'px';
571 });
572 var apiEvent = fontSizeSettings[fontSizeKey].onChanged;
573 apiEvent.addListener(
574 advancedFonts.getFontSizeChangedOnBrowserFunc(slider, label, samples));
575 }
576
577 /**
578 * Clears the font settings for the specified script.
579 * @param {string} script The script code.
580 */
581 advancedFonts.clearSettingsForScript = function(script) {
582 advancedFonts.pendingChanges.clearOneScript(script);
583 for (var i = 0; i < advancedFonts.FAMILIES.length; i++) {
397 chrome.fontSettings.clearFont({ 584 chrome.fontSettings.clearFont({
398 script: script, 585 script: script,
399 genericFamily: families[i] 586 genericFamily: advancedFonts.FAMILIES[i]
400 }); 587 });
401 } 588 }
402 } 589 }
403 590
404 function clearAllSettings() { 591 /**
405 for (var i = 0; i < scripts.length; i++) 592 * Clears all font and font size settings.
406 clearSettingsForScript(scripts[i].scriptCode); 593 */
407 594 advancedFonts.clearAllSettings = function() {
595 advancedFonts.pendingChanges.clear();
596 for (var i = 0; i < advancedFonts.scripts.length; i++)
597 advancedFonts.clearSettingsForScript(advancedFonts.scripts[i].scriptCode);
408 chrome.fontSettings.clearDefaultFixedFontSize(); 598 chrome.fontSettings.clearDefaultFixedFontSize();
409 chrome.fontSettings.clearDefaultFontSize(); 599 chrome.fontSettings.clearDefaultFontSize();
410 chrome.fontSettings.clearMinimumFontSize(); 600 chrome.fontSettings.clearMinimumFontSize();
411 } 601 }
412 602
413 function closeOverlay() { 603 /**
604 * Closes the overlay.
605 */
606 advancedFonts.closeOverlay = function() {
414 $('overlay-container').hidden = true; 607 $('overlay-container').hidden = true;
415 } 608 }
416 609
417 function initResetButtons() { 610 /**
611 * Initializes apply and reset buttons.
612 */
613 advancedFonts.initApplyAndResetButtons = function() {
614 var applyButton = $('apply-settings');
615 applyButton.addEventListener('click', function() {
616 advancedFonts.pendingChanges.apply();
617 advancedFonts.refresh();
618 });
619
418 var overlay = $('overlay-container'); 620 var overlay = $('overlay-container');
419 cr.ui.overlay.globalInitialization(); 621 cr.ui.overlay.globalInitialization();
420 cr.ui.overlay.setupOverlay(overlay); 622 cr.ui.overlay.setupOverlay(overlay);
421 overlay.addEventListener('cancelOverlay', closeOverlay); 623 overlay.addEventListener('cancelOverlay', advancedFonts.closeOverlay);
422 624
423 $('reset-this-script-button').onclick = function(event) { 625 $('reset-this-script-button').onclick = function(event) {
424 var scriptName = $('scriptList').selectedItem.scriptName; 626 var scriptList = $('scriptList');
627 var scriptName = scriptList.options[scriptList.selectedIndex].text;
425 $('reset-this-script-overlay-dialog-content').innerText = 628 $('reset-this-script-overlay-dialog-content').innerText =
426 'Are you sure you want to reset settings for ' + scriptName + 629 'Are you sure you want to reset settings for ' + scriptName +
427 ' script?'; 630 ' script?';
428 631
429 $('overlay-container').hidden = false; 632 $('overlay-container').hidden = false;
430 $('reset-this-script-overlay-dialog').hidden = false; 633 $('reset-this-script-overlay-dialog').hidden = false;
431 $('reset-all-scripts-overlay-dialog').hidden = true; 634 $('reset-all-scripts-overlay-dialog').hidden = true;
432 } 635 };
433 $('reset-this-script-ok').onclick = function(event) { 636 $('reset-this-script-ok').onclick = function(event) {
434 clearSettingsForScript(getSelectedScript()); 637 advancedFonts.clearSettingsForScript(advancedFonts.getSelectedScript());
435 closeOverlay(); 638 advancedFonts.closeOverlay();
639 advancedFonts.refresh();
436 }; 640 };
437 $('reset-this-script-cancel').onclick = closeOverlay; 641 $('reset-this-script-cancel').onclick = advancedFonts.closeOverlay;
438 642
439 $('reset-all-button').onclick = function(event) { 643 $('reset-all-button').onclick = function(event) {
440 $('overlay-container').hidden = false; 644 $('overlay-container').hidden = false;
441 $('reset-all-scripts-overlay-dialog').hidden = false; 645 $('reset-all-scripts-overlay-dialog').hidden = false;
442 $('reset-this-script-overlay-dialog').hidden = true; 646 $('reset-this-script-overlay-dialog').hidden = true;
443 } 647 };
444 $('reset-all-ok').onclick = function(event) { 648 $('reset-all-ok').onclick = function(event) {
445 clearAllSettings(); 649 advancedFonts.clearAllSettings();
446 closeOverlay(); 650 advancedFonts.closeOverlay();
447 } 651 advancedFonts.refresh();
448 $('reset-all-cancel').onclick = closeOverlay; 652 };
653 $('reset-all-cancel').onclick = advancedFonts.closeOverlay;
449 } 654 }
450 655
451 function init() { 656 /**
452 var scriptList = document.getElementById('scriptList'); 657 * Best guess for system fonts, taken from the IDS_WEB_FONT_FAMILY strings in
453 fontSettings.ui.ScriptList.decorate(scriptList); 658 * Chrome.
454 scriptList.selectionModel.selectedIndex = 0; 659 * TODO: The font should be localized like Chrome does.
455 scriptList.selectionModel.addEventListener('change', 660 * @const
456 updateFontListsForScript); 661 */
457 662 advancedFonts.systemFonts = {
458 // Populate the font lists. 663 cros: 'Noto Sans UI, sans-serif',
459 chrome.fontSettings.getFontList(populateLists); 664 linux: 'Ubuntu, sans-serif',
460 665 mac: 'Lucida Grande, sans-serif',
461 // Add change handlers to the font lists. 666 win: 'Segoe UI, Tahoma, sans-serif',
462 for (var i = 0; i < fontPickers.length; i++) { 667 unknown: 'sans-serif'
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 } 668 }
510 669
511 document.addEventListener('DOMContentLoaded', init); 670 /**
671 * @return {string} The platform this extension is running on.
672 */
673 advancedFonts.getPlatform = function() {
674 var ua = window.navigator.appVersion;
675 if (ua.indexOf('Win') != -1) return 'win';
676 if (ua.indexOf('Mac') != -1) return 'mac';
677 if (ua.indexOf('Linux') != -1) return 'linux';
678 if (ua.indexOf('CrOS') != -1) return 'cros';
679 return 'unknown';
680 }
681
682 /**
683 * Chrome settings tries to use the system font. So does this extension.
684 */
685 advancedFonts.useSystemFont = function() {
686 document.body.style.fontFamily =
687 advancedFonts.systemFonts[advancedFonts.getPlatform()];
688 }
689
690 /**
691 * Sorts the list of script codes by scriptName. Someday this extension will
692 * have localized script names, so the order will depend on locale.
693 */
694 advancedFonts.sortScripts = function() {
695 var i;
696 var scripts = advancedFonts.scripts;
697 for (i = 0; i < scripts; ++i) {
698 if (scripts[i].scriptCode == advancedFonts.COMMON_SCRIPT)
699 break;
700 }
701 var defaultScript = scripts.splice(i, 1)[0];
702
703 scripts.sort(function(a, b) {
704 if (a.scriptName > b.scriptName)
705 return 1;
706 if (a.scriptName < b.scriptName)
707 return -1;
708 return 0;
709 });
710
711 scripts.unshift(defaultScript);
712 }
713
714 /**
715 * Initializes UI controls for font settings.
716 */
717 advancedFonts.initFontControls = function() {
718 advancedFonts.fontSettings = {
719 'standard': {
720 fontList: $('standardFontList'),
721 samples: [$('standardFontSample'), $('minFontSample')]
722 },
723 'serif': {
724 fontList: $('serifFontList'),
725 samples: [$('serifFontSample')]
726 },
727 'sansserif': {
728 fontList: $('sansSerifFontList'),
729 samples: [$('sansSerifFontSample')]
730 },
731 'fixed': {
732 fontList: $('fixedFontList'),
733 samples: [$('fixedFontSample')]
734 }
735 };
736
737 for (var genericFamily in advancedFonts.fontSettings) {
738 var list = advancedFonts.fontSettings[genericFamily].fontList;
739 list.addEventListener('change', advancedFonts.getFontChangeHandler(
740 list, genericFamily));
741 }
742 chrome.fontSettings.onFontChanged.addListener(advancedFonts.refresh);
743 chrome.fontSettings.getFontList(advancedFonts.populateFontLists);
744 }
745
746 /**
747 * Initializes UI controls for font size settings.
748 */
749 advancedFonts.initFontSizeControls = function() {
750 advancedFonts.fontSizeSettings = {
751 'defaultFontSize': {
752 sliderContainer: $('defaultFontSizeSliderContainer'),
753 minValue: 6,
754 maxValue: 50,
755 samples: [
756 $('standardFontSample'), $('serifFontSample'), $('sansSerifFontSample')
757 ],
758 label: $('defaultFontSizeLabel'),
759 getter: chrome.fontSettings.getDefaultFontSize,
760 onChanged: chrome.fontSettings.onDefaultFontSizeChanged
761 },
762 'defaultFixedFontSize': {
763 sliderContainer: $('defaultFixedFontSizeSliderContainer'),
764 minValue: 6,
765 maxValue: 50,
766 samples: [$('fixedFontSample')],
767 label: $('fixedFontSizeLabel'),
768 getter: chrome.fontSettings.getDefaultFixedFontSize,
769 onChanged: chrome.fontSettings.onDefaultFixedFontSizeChanged
770 },
771 'minFontSize': {
772 sliderContainer: $('minFontSizeSliderContainer'),
773 minValue: 6,
774 maxValue: 24,
775 samples: [$('minFontSample')],
776 label: $('minFontSizeLabel'),
777 getter: chrome.fontSettings.getMinimumFontSize,
778 onChanged: chrome.fontSettings.onMinimumFontSizeChanged
779 }
780 };
781
782 for (var fontSizeKey in advancedFonts.fontSizeSettings)
783 advancedFonts.initFontSizeSetting(fontSizeKey);
784 }
785
786 /**
787 * Initializes the list of scripts.
788 */
789 advancedFonts.initScriptList = function() {
790 var scriptList = $('scriptList');
791 advancedFonts.sortScripts();
792 var scripts = advancedFonts.scripts;
793 for (var i = 0; i < scripts.length; i++) {
794 var script = document.createElement('option');
795 script.value = scripts[i].scriptCode;
796 script.text = scripts[i].scriptName;
797 scriptList.add(script);
798 }
799 scriptList.selectedIndex = 0;
800 scriptList.addEventListener('change', advancedFonts.refresh);
801 }
802
803 /**
804 * Initializes the extension.
805 */
806 advancedFonts.init = function() {
807 advancedFonts.useSystemFont();
808
809 advancedFonts.initFontControls();
810 advancedFonts.initFontSizeControls();
811 advancedFonts.initScriptList();
812
813 advancedFonts.initApplyAndResetButtons();
814 }
815
816 document.addEventListener('DOMContentLoaded', advancedFonts.init);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698