// Copyright (c) 2012 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. cr.define('print_preview', function() { 'use strict'; /** * Creates a PageSettings object. This object encapsulates all settings and * logic related to page selection. * @param {!print_preview.ticket_items.PageRange} pageRangeTicketItem Used to * read and write page range settings. * @constructor * @extends {print_preview.SettingsSection} */ function PageSettings(pageRangeTicketItem) { print_preview.SettingsSection.call(this); /** * Used to read and write page range settings. * @type {!print_preview.ticket_items.PageRange} * @private */ this.pageRangeTicketItem_ = pageRangeTicketItem; /** * Timeout used to delay processing of the custom page range input. * @type {?number} * @private */ this.customInputTimeout_ = null; /** * Custom page range input. * @type {HTMLInputElement} * @private */ this.customInput_ = null; /** * Custom page range radio button. * @type {HTMLInputElement} * @private */ this.customRadio_ = null; /** * All page rage radio button. * @type {HTMLInputElement} * @private */ this.allRadio_ = null; /** * Container of a hint to show when the custom page range is invalid. * @type {HTMLElement} * @private */ this.customHintEl_ = null; }; /** * CSS classes used by the page settings. * @enum {string} * @private */ PageSettings.Classes_ = { ALL_RADIO: 'page-settings-all-radio', CUSTOM_HINT: 'page-settings-custom-hint', CUSTOM_INPUT: 'page-settings-custom-input', CUSTOM_RADIO: 'page-settings-custom-radio' }; /** * Delay in milliseconds before processing custom page range input. * @type {number} * @private */ PageSettings.CUSTOM_INPUT_DELAY_ = 500; PageSettings.prototype = { __proto__: print_preview.SettingsSection.prototype, /** @override */ isAvailable: function() { return this.pageRangeTicketItem_.isCapabilityAvailable(); }, /** @override */ hasCollapsibleContent: function() { return false; }, /** @override */ set isEnabled(isEnabled) { this.customInput_.disabled = !isEnabled; this.allRadio_.disabled = !isEnabled; this.customRadio_.disabled = !isEnabled; }, /** @override */ enterDocument: function() { print_preview.SettingsSection.prototype.enterDocument.call(this); this.tracker.add( this.allRadio_, 'click', this.onAllRadioClick_.bind(this)); this.tracker.add( this.customRadio_, 'click', this.onCustomRadioClick_.bind(this)); this.tracker.add( this.customInput_, 'blur', this.onCustomInputBlur_.bind(this)); this.tracker.add( this.customInput_, 'focus', this.onCustomInputFocus_.bind(this)); this.tracker.add( this.customInput_, 'keydown', this.onCustomInputKeyDown_.bind(this)); this.tracker.add( this.customInput_, 'input', this.onCustomInputChange_.bind(this)); this.tracker.add( this.pageRangeTicketItem_, print_preview.ticket_items.TicketItem.EventType.CHANGE, this.onPageRangeTicketItemChange_.bind(this)); }, /** @override */ exitDocument: function() { print_preview.SettingsSection.prototype.exitDocument.call(this); this.customInput_ = null; this.customRadio_ = null; this.allRadio_ = null; this.customHintEl_ = null; }, /** @override */ decorateInternal: function() { this.customInput_ = this.getElement().getElementsByClassName( PageSettings.Classes_.CUSTOM_INPUT)[0]; this.allRadio_ = this.getElement().getElementsByClassName( PageSettings.Classes_.ALL_RADIO)[0]; this.customRadio_ = this.getElement().getElementsByClassName( PageSettings.Classes_.CUSTOM_RADIO)[0]; this.customHintEl_ = this.getElement().getElementsByClassName( PageSettings.Classes_.CUSTOM_HINT)[0]; }, /** * @param {!PageRangeStatus} validity (of page range) * @private */ setInvalidStateVisible_: function(validity) { if (validity !== PageRangeStatus.NO_ERROR) { var message; if (validity === PageRangeStatus.LIMIT_ERROR) { if (this.pageRangeTicketItem_.getDocumentNumPages()) { message = loadTimeData.getStringF( 'pageRangeLimitInstructionWithValue', this.pageRangeTicketItem_.getDocumentNumPages()); } else { message = loadTimeData.getString( 'pageRangeLimitInstruction'); } } else { message = loadTimeData.getStringF( 'pageRangeSyntaxInstruction', loadTimeData.getString('examplePageRangeText')); } this.customHintEl_.textContent = message; this.customInput_.classList.add('invalid'); fadeInElement(this.customHintEl_); } else { this.customInput_.classList.remove('invalid'); fadeOutElement(this.customHintEl_); } }, /** * Called when the all radio button is clicked. Updates the print ticket. * @private */ onAllRadioClick_: function() { this.pageRangeTicketItem_.updateValue(null); }, /** * Called when the custom radio button is clicked. Updates the print ticket. * @private */ onCustomRadioClick_: function() { this.customInput_.focus(); }, /** * Called when the custom input is blurred. Enables the all radio button if * the custom input is empty. * @private */ onCustomInputBlur_: function(event) { if (this.customInput_.value == '' && event.relatedTarget != this.customRadio_) { this.allRadio_.checked = true; } }, /** * Called when the custom input is focused. * @private */ onCustomInputFocus_: function() { this.customRadio_.checked = true; this.pageRangeTicketItem_.updateValue(this.customInput_.value); }, /** * Called when a key is pressed on the custom input. * @param {Event} event Contains the key that was pressed. * @private */ onCustomInputKeyDown_: function(event) { if (event.keyCode == 13 /*enter*/) { if (this.customInputTimeout_) { clearTimeout(this.customInputTimeout_); this.customInputTimeout_ = null; } this.pageRangeTicketItem_.updateValue(this.customInput_.value); } }, /** * Called after a delay following a key press in the custom input. * @private */ onCustomInputTimeout_: function() { this.customInputTimeout_ = null; if (this.customRadio_.checked) { this.pageRangeTicketItem_.updateValue(this.customInput_.value); } }, /** * Called for events that change the text - undo, redo, paste and * keystrokes outside of enter, copy, etc. (Re)starts the * re-evaluation timer. * @private */ onCustomInputChange_: function() { if (this.customInputTimeout_) clearTimeout(this.customInputTimeout_); this.customInputTimeout_ = setTimeout( this.onCustomInputTimeout_.bind(this), PageSettings.CUSTOM_INPUT_DELAY_); }, /** * Called when the print ticket changes. Updates the state of the component. * @private */ onPageRangeTicketItemChange_: function() { if (this.isAvailable()) { var pageRangeStr = this.pageRangeTicketItem_.getValue(); if (pageRangeStr || this.customRadio_.checked) { if (!document.hasFocus() || document.activeElement != this.customInput_) { this.customInput_.value = pageRangeStr; } this.customRadio_.checked = true; this.setInvalidStateVisible_( this.pageRangeTicketItem_.checkValidity()); } else { this.allRadio_.checked = true; this.setInvalidStateVisible_(PageRangeStatus.NO_ERROR); } } this.updateUiStateInternal(); } }; // Export return { PageSettings: PageSettings }; });