| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'chrome://resources/cr_components/managed_dialog/managed_dialog.js'; |
| import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; |
| import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; |
| import 'chrome://resources/cr_elements/shared_style_css.m.js'; |
| import 'chrome://resources/cr_elements/md_select_css.m.js'; |
| import '../controls/controlled_radio_button.js'; |
| import '../controls/extension_controlled_indicator.js'; |
| import '../controls/settings_radio_group.js'; |
| import '../controls/settings_toggle_button.js'; |
| import '../settings_page/settings_animated_pages.js'; |
| import '../settings_page/settings_subpage.js'; |
| import '../settings_shared_css.js'; |
| import '../settings_vars_css.js'; |
| import './home_url_input.js'; |
| import '../controls/settings_dropdown_menu.js'; |
| |
| import {assert} from 'chrome://resources/js/assert.m.js'; |
| import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js'; |
| import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
| |
| import {BaseMixin} from '../base_mixin.js'; |
| import {DropdownMenuOptionList} from '../controls/settings_dropdown_menu.js'; |
| import {SettingsDropdownMenuElement} from '../controls/settings_dropdown_menu.js'; |
| import {loadTimeData} from '../i18n_setup.js'; |
| import {AppearancePageVisibility} from '../page_visibility.js'; |
| import {PrefsMixin} from '../prefs/prefs_mixin.js'; |
| import {routes} from '../route.js'; |
| import {Router} from '../router.js'; |
| |
| import {AppearanceBrowserProxy, AppearanceBrowserProxyImpl} from './appearance_browser_proxy.js'; |
| import {getTemplate} from './appearance_page.html.js'; |
| |
| |
| /** |
| * This is the absolute difference maintained between standard and |
| * fixed-width font sizes. http://crbug.com/91922. |
| */ |
| const SIZE_DIFFERENCE_FIXED_STANDARD: number = 3; |
| |
| /** |
| * ID for autogenerated themes. Should match |
| * |ThemeService::kAutogeneratedThemeID|. |
| */ |
| const AUTOGENERATED_THEME_ID: string = 'autogenerated_theme_id'; |
| |
| /** |
| * 'settings-appearance-page' is the settings page containing appearance |
| * settings. |
| */ |
| |
| export interface SettingsAppearancePageElement { |
| $: { |
| defaultFontSize: SettingsDropdownMenuElement, |
| zoomLevel: HTMLSelectElement, |
| }; |
| } |
| |
| const SettingsAppearancePageElementBase = |
| I18nMixin(PrefsMixin(BaseMixin(PolymerElement))); |
| |
| export class SettingsAppearancePageElement extends |
| SettingsAppearancePageElementBase { |
| static get is() { |
| return 'settings-appearance-page'; |
| } |
| |
| static get template() { |
| return getTemplate(); |
| } |
| |
| static get properties() { |
| return { |
| /** |
| * Dictionary defining page visibility. |
| */ |
| pageVisibility: Object, |
| |
| prefs: { |
| type: Object, |
| notify: true, |
| }, |
| |
| defaultZoom_: Number, |
| |
| isWallpaperPolicyControlled_: {type: Boolean, value: true}, |
| |
| /** |
| * List of options for the font size drop-down menu. |
| */ |
| fontSizeOptions_: { |
| readOnly: true, |
| type: Array, |
| value() { |
| return [ |
| {value: 9, name: loadTimeData.getString('verySmall')}, |
| {value: 12, name: loadTimeData.getString('small')}, |
| {value: 16, name: loadTimeData.getString('medium')}, |
| {value: 20, name: loadTimeData.getString('large')}, |
| {value: 24, name: loadTimeData.getString('veryLarge')}, |
| ]; |
| }, |
| }, |
| |
| /** |
| * Predefined zoom factors to be used when zooming in/out. These are in |
| * ascending order. Values are displayed in the page zoom drop-down menu |
| * as percentages. |
| */ |
| pageZoomLevels_: Array, |
| |
| themeSublabel_: String, |
| |
| themeUrl_: String, |
| |
| useSystemTheme_: { |
| type: Boolean, |
| value: |
| false, // Can only be true on Linux, but value exists everywhere. |
| }, |
| |
| focusConfig_: { |
| type: Object, |
| value() { |
| const map = new Map(); |
| if (routes.FONTS) { |
| map.set(routes.FONTS.path, '#customize-fonts-subpage-trigger'); |
| } |
| return map; |
| }, |
| }, |
| |
| showReaderModeOption_: { |
| type: Boolean, |
| value() { |
| return loadTimeData.getBoolean('showReaderModeOption'); |
| }, |
| }, |
| |
| isForcedTheme_: { |
| type: Boolean, |
| computed: 'computeIsForcedTheme_(' + |
| 'prefs.autogenerated.theme.policy.color.controlledBy)', |
| }, |
| |
| // <if expr="is_linux and not chromeos and not lacros"> |
| /** |
| * Whether to show the "Custom Chrome Frame" setting. |
| */ |
| showCustomChromeFrame_: { |
| type: Boolean, |
| value() { |
| return loadTimeData.getBoolean('showCustomChromeFrame'); |
| }, |
| }, |
| // </if> |
| |
| showManagedThemeDialog_: Boolean, |
| }; |
| } |
| |
| static get observers() { |
| return [ |
| 'defaultFontSizeChanged_(prefs.webkit.webprefs.default_font_size.value)', |
| 'themeChanged_(' + |
| 'prefs.extensions.theme.id.value, useSystemTheme_, isForcedTheme_)', |
| |
| // <if expr="is_linux and not chromeos"> |
| // NOTE: this pref only exists on Linux. |
| 'useSystemThemePrefChanged_(prefs.extensions.theme.use_system.value)', |
| // </if> |
| ]; |
| } |
| |
| pageVisibility: AppearancePageVisibility; |
| private defaultZoom_: number; |
| private isWallpaperPolicyControlled_: boolean; |
| private fontSizeOptions_: DropdownMenuOptionList; |
| private pageZoomLevels_: number[]; |
| private themeSublabel_: string; |
| private themeUrl_: string; |
| private useSystemTheme_: boolean; |
| private focusConfig_: Map<string, string>; |
| private showReaderModeOption_: boolean; |
| private isForcedTheme_: boolean; |
| |
| // <if expr="is_linux and not chromeos and not lacros"> |
| private showCustomChromeFrame_: boolean; |
| // </if> |
| |
| private showManagedThemeDialog_: boolean; |
| private appearanceBrowserProxy_: AppearanceBrowserProxy = |
| AppearanceBrowserProxyImpl.getInstance(); |
| |
| ready() { |
| super.ready(); |
| |
| this.$.defaultFontSize.menuOptions = this.fontSizeOptions_; |
| // TODO(dschuyler): Look into adding a listener for the |
| // default zoom percent. |
| this.appearanceBrowserProxy_.getDefaultZoom().then(zoom => { |
| this.defaultZoom_ = zoom; |
| }); |
| |
| this.pageZoomLevels_ = |
| JSON.parse(loadTimeData.getString('presetZoomFactors')); |
| } |
| |
| /** @return A zoom easier read by users. */ |
| private formatZoom_(zoom: number): number { |
| return Math.round(zoom * 100); |
| } |
| |
| /** |
| * @param showHomepage Whether to show home page. |
| * @param isNtp Whether to use the NTP as the home page. |
| * @param homepageValue If not using NTP, use this URL. |
| */ |
| private getShowHomeSubLabel_( |
| showHomepage: boolean, isNtp: boolean, homepageValue: string): string { |
| if (!showHomepage) { |
| return this.i18n('homeButtonDisabled'); |
| } |
| if (isNtp) { |
| return this.i18n('homePageNtp'); |
| } |
| return homepageValue || this.i18n('customWebAddress'); |
| } |
| |
| private onCustomizeFontsTap_() { |
| Router.getInstance().navigateTo(routes.FONTS); |
| } |
| |
| private onDisableExtension_() { |
| this.dispatchEvent(new CustomEvent( |
| 'refresh-pref', {bubbles: true, composed: true, detail: 'homepage'})); |
| } |
| |
| /** |
| * @param value The changed font size slider value. |
| */ |
| private defaultFontSizeChanged_(value: number) { |
| // This pref is handled separately in some extensions, but here it is tied |
| // to default_font_size (to simplify the UI). |
| this.set( |
| 'prefs.webkit.webprefs.default_fixed_font_size.value', |
| value - SIZE_DIFFERENCE_FIXED_STANDARD); |
| } |
| |
| /** |
| * Open URL for either current theme or the theme gallery. |
| */ |
| private openThemeUrl_() { |
| window.open(this.themeUrl_ || loadTimeData.getString('themesGalleryUrl')); |
| } |
| |
| private onUseDefaultTap_() { |
| if (this.isForcedTheme_) { |
| this.showManagedThemeDialog_ = true; |
| return; |
| } |
| this.appearanceBrowserProxy_.useDefaultTheme(); |
| } |
| |
| // <if expr="is_linux and not chromeos"> |
| private useSystemThemePrefChanged_(useSystemTheme: boolean) { |
| this.useSystemTheme_ = useSystemTheme; |
| } |
| |
| /** @return Whether to show the "USE CLASSIC" button. */ |
| private showUseClassic_(themeId: string, useSystemTheme: boolean): boolean { |
| return !!themeId || useSystemTheme; |
| } |
| |
| /** @return Whether to show the "USE GTK+" button. */ |
| private showUseSystem_(themeId: string, useSystemTheme: boolean): boolean { |
| return (!!themeId || !useSystemTheme) && |
| !this.appearanceBrowserProxy_.isChildAccount(); |
| } |
| |
| /** |
| * @return Whether to show the secondary area where "USE CLASSIC" and |
| * "USE GTK+" buttons live. |
| */ |
| private showThemesSecondary_(themeId: string, useSystemTheme: boolean): |
| boolean { |
| return this.showUseClassic_(themeId, useSystemTheme) || |
| this.showUseSystem_(themeId, useSystemTheme); |
| } |
| |
| private onUseSystemTap_() { |
| if (this.isForcedTheme_) { |
| this.showManagedThemeDialog_ = true; |
| return; |
| } |
| this.appearanceBrowserProxy_.useSystemTheme(); |
| } |
| // </if> |
| |
| private themeChanged_( |
| themeId: string, useSystemTheme: boolean, isForcedTheme: boolean) { |
| if (this.prefs === undefined || useSystemTheme === undefined) { |
| return; |
| } |
| |
| if (themeId.length > 0 && themeId !== AUTOGENERATED_THEME_ID && |
| !isForcedTheme) { |
| assert(!useSystemTheme); |
| |
| this.appearanceBrowserProxy_.getThemeInfo(themeId).then(info => { |
| this.themeSublabel_ = info.name; |
| }); |
| |
| this.themeUrl_ = 'https://chrome.google.com/webstore/detail/' + themeId; |
| return; |
| } |
| |
| this.themeUrl_ = ''; |
| |
| if (themeId === AUTOGENERATED_THEME_ID || isForcedTheme) { |
| this.themeSublabel_ = this.i18n('chromeColors'); |
| return; |
| } |
| |
| let i18nId; |
| // <if expr="is_linux and not chromeos and not lacros"> |
| i18nId = useSystemTheme ? 'systemTheme' : 'classicTheme'; |
| // </if> |
| // <if expr="not is_linux or chromeos_ash or chromeos_lacros"> |
| i18nId = 'chooseFromWebStore'; |
| // </if> |
| this.themeSublabel_ = this.i18n(i18nId); |
| } |
| |
| /** @return Whether applied theme is set by policy. */ |
| private computeIsForcedTheme_(): boolean { |
| return !!this.getPref('autogenerated.theme.policy.color').controlledBy; |
| } |
| |
| private onZoomLevelChange_() { |
| chrome.settingsPrivate.setDefaultZoom(parseFloat(this.$.zoomLevel.value)); |
| } |
| |
| /** @see blink::PageZoomValuesEqual(). */ |
| private zoomValuesEqual_(zoom1: number, zoom2: number): boolean { |
| return Math.abs(zoom1 - zoom2) <= 0.001; |
| } |
| |
| private showHr_(previousIsVisible: boolean, nextIsVisible: boolean): boolean { |
| return previousIsVisible && nextIsVisible; |
| } |
| |
| private onManagedDialogClosed_() { |
| this.showManagedThemeDialog_ = false; |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'settings-appearance-page': SettingsAppearancePageElement; |
| } |
| } |
| |
| customElements.define( |
| SettingsAppearancePageElement.is, SettingsAppearancePageElement); |