| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js'; |
| import 'chrome://resources/cr_elements/cr_input/cr_input.js'; |
| import 'chrome://resources/cr_elements/cr_collapse/cr_collapse.js'; |
| import './print_preview_shared.css.js'; |
| import './settings_section.js'; |
| |
| import type {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js'; |
| import type {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js'; |
| import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; |
| import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; |
| import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
| |
| import {State} from '../data/state.js'; |
| |
| import {InputMixin} from './input_mixin.js'; |
| import {getTemplate} from './pin_settings.html.js'; |
| import {SettingsMixin} from './settings_mixin.js'; |
| |
| export interface PrintPreviewPinSettingsElement { |
| $: { |
| pin: CrCheckboxElement, |
| pinValue: CrInputElement, |
| }; |
| } |
| |
| const PrintPreviewPinSettingsElementBase = |
| WebUiListenerMixin(InputMixin(SettingsMixin(I18nMixin(PolymerElement)))); |
| |
| export class PrintPreviewPinSettingsElement extends |
| PrintPreviewPinSettingsElementBase { |
| static get is() { |
| return 'print-preview-pin-settings'; |
| } |
| |
| static get template() { |
| return getTemplate(); |
| } |
| |
| static get properties() { |
| return { |
| state: Number, |
| |
| disabled: Boolean, |
| |
| checkboxDisabled_: { |
| type: Boolean, |
| computed: 'computeCheckboxDisabled_(inputValid_, disabled, ' + |
| 'settings.pin.setByGlobalPolicy)', |
| }, |
| |
| pinEnabled_: { |
| type: Boolean, |
| value: false, |
| }, |
| |
| inputString_: { |
| type: String, |
| value: '', |
| observer: 'onInputChanged_', |
| }, |
| |
| isPinValid: { |
| type: Boolean, |
| reflectToAttribute: true, |
| notify: true, |
| }, |
| }; |
| } |
| |
| static get observers() { |
| return [ |
| 'onSettingsChanged_(settings.pin.value, settings.pinValue.value)', |
| 'changePinValueSetting_(state)', |
| ]; |
| } |
| |
| state: State; |
| disabled: boolean; |
| isPinValid: boolean; |
| private checkboxDisabled_: boolean; |
| private inputString_: string; |
| private pinEnabled_: boolean; |
| |
| override ready() { |
| super.ready(); |
| |
| this.addEventListener('input-change', e => this.onInputChange_(e)); |
| } |
| |
| /** @return The cr-input field element for InputMixin. */ |
| override getInput() { |
| return this.$.pinValue; |
| } |
| |
| private onInputChange_(e: CustomEvent<string>) { |
| this.inputString_ = e.detail; |
| } |
| |
| private onCollapseChanged_() { |
| if (this.pinEnabled_) { |
| this.$.pinValue.focusInput(); |
| } |
| } |
| |
| /** |
| * @param inputValid Whether pin value is valid. |
| * @param disabled Whether pin setting is disabled. |
| * @param managed Whether pin setting is managed. |
| * @return Whether pin checkbox should be disabled. |
| */ |
| private computeCheckboxDisabled_( |
| inputValid: boolean, disabled: boolean, managed: boolean): boolean { |
| return managed || (inputValid && disabled); |
| } |
| |
| /** |
| * @return Whether to disable the pin value input. |
| */ |
| private inputDisabled_(): boolean { |
| return !this.pinEnabled_ || (this.isPinValid && this.disabled); |
| } |
| |
| /** |
| * Updates the checkbox state when the setting has been initialized. |
| */ |
| private onSettingsChanged_() { |
| const pinEnabled = this.getSetting('pin').value as boolean; |
| this.$.pin.checked = pinEnabled; |
| this.pinEnabled_ = pinEnabled; |
| const pinValue = this.getSetting('pinValue'); |
| this.inputString_ = pinValue.value as string; |
| this.resetString(); |
| } |
| |
| private onPinChange_() { |
| this.setSetting('pin', this.$.pin.checked); |
| // We need to set validity of pinValue to true to return to READY state |
| // after unchecking the pin and to check the validity again after checking |
| // the pin. |
| if (!this.$.pin.checked) { |
| this.isPinValid = true; |
| } else { |
| this.changePinValueSetting_(); |
| } |
| } |
| |
| private onInputChanged_() { |
| this.changePinValueSetting_(); |
| } |
| |
| /** |
| * Updates pin value setting based on the current value of the pin value |
| * input. |
| */ |
| private changePinValueSetting_() { |
| if (this.settings === undefined) { |
| return; |
| } |
| |
| // Return early if pinValue is not available; unavailable settings should |
| // not be set, but this function observes |state| which may change |
| // regardless of pin availability. |
| if (!this.settings.pinValue.available) { |
| return; |
| } |
| |
| // If the state is not READY and current pinValue is valid (so it's not the |
| // cause of the error) we need to wait until the state will be READY again. |
| // It's done because we don't permit multiple simultaneous validation errors |
| // in Print Preview and we also don't want to set the value when sticky |
| // settings may not yet have been set. |
| if (this.state !== State.READY && this.settings.pinValue.valid) { |
| return; |
| } |
| this.isPinValid = this.computeValid_(); |
| |
| // We allow to save the empty string as sticky setting value to give users |
| // the opportunity to unset their PIN in sticky settings. |
| if ((this.isPinValid || this.inputString_ === '') && |
| this.inputString_ !== this.getSettingValue('pinValue')) { |
| this.setSetting('pinValue', this.inputString_); |
| } |
| } |
| |
| /** |
| * @return Whether input value represented by inputString_ is |
| * valid, so that it can be used to update the setting. |
| */ |
| private computeValid_(): boolean { |
| // Make sure value updates first, in case inputString_ was updated by JS. |
| this.$.pinValue.value = this.inputString_; |
| return this.$.pinValue.validate(); |
| } |
| |
| private getPinErrorMessage_(): string { |
| return this.isPinValid ? '' : this.i18n('pinErrorMessage'); |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'print-preview-pin-settings': PrintPreviewPinSettingsElement; |
| } |
| } |
| |
| |
| customElements.define( |
| PrintPreviewPinSettingsElement.is, PrintPreviewPinSettingsElement); |