- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / print_preview / settings / page_settings.js
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 cr.define('print_preview', function() {
6   'use strict';
7
8   /**
9    * Creates a PageSettings object. This object encapsulates all settings and
10    * logic related to page selection.
11    * @param {!print_preview.ticket_items.PageRange} pageRangeTicketItem Used to
12    *     read and write page range settings.
13    * @constructor
14    * @extends {print_preview.Component}
15    */
16   function PageSettings(pageRangeTicketItem) {
17     print_preview.Component.call(this);
18
19     /**
20      * Used to read and write page range settings.
21      * @type {!print_preview.ticket_items.PageRange}
22      * @private
23      */
24     this.pageRangeTicketItem_ = pageRangeTicketItem;
25
26     /**
27      * Timeout used to delay processing of the custom page range input.
28      * @type {?number}
29      * @private
30      */
31     this.customInputTimeout_ = null;
32
33     /**
34      * Custom page range input.
35      * @type {HTMLInputElement}
36      * @private
37      */
38     this.customInput_ = null;
39
40     /**
41      * Custom page range radio button.
42      * @type {HTMLInputElement}
43      * @private
44      */
45     this.customRadio_ = null;
46
47     /**
48      * All page rage radio button.
49      * @type {HTMLInputElement}
50      * @private
51      */
52     this.allRadio_ = null;
53
54     /**
55      * Container of a hint to show when the custom page range is invalid.
56      * @type {HTMLElement}
57      * @private
58      */
59     this.customHintEl_ = null;
60   };
61
62   /**
63    * CSS classes used by the page settings.
64    * @enum {string}
65    * @private
66    */
67   PageSettings.Classes_ = {
68     ALL_RADIO: 'page-settings-all-radio',
69     CUSTOM_HINT: 'page-settings-custom-hint',
70     CUSTOM_INPUT: 'page-settings-custom-input',
71     CUSTOM_RADIO: 'page-settings-custom-radio'
72   };
73
74   /**
75    * Delay in milliseconds before processing custom page range input.
76    * @type {number}
77    * @private
78    */
79   PageSettings.CUSTOM_INPUT_DELAY_ = 500;
80
81   PageSettings.prototype = {
82     __proto__: print_preview.Component.prototype,
83
84     set isEnabled(isEnabled) {
85       this.customInput_.disabled = !isEnabled;
86       this.allRadio_.disabled = !isEnabled;
87       this.customRadio_.disabled = !isEnabled;
88     },
89
90     /** @override */
91     enterDocument: function() {
92       print_preview.Component.prototype.enterDocument.call(this);
93       this.tracker.add(
94           this.allRadio_, 'click', this.onAllRadioClick_.bind(this));
95       this.tracker.add(
96           this.customRadio_, 'click', this.onCustomRadioClick_.bind(this));
97       this.tracker.add(
98           this.customInput_, 'blur', this.onCustomInputBlur_.bind(this));
99       this.tracker.add(
100           this.customInput_, 'focus', this.onCustomInputFocus_.bind(this));
101       this.tracker.add(
102           this.customInput_, 'keyup', this.onCustomInputKeyUp_.bind(this));
103       this.tracker.add(
104           this.pageRangeTicketItem_,
105           print_preview.ticket_items.TicketItem.EventType.CHANGE,
106           this.onPageRangeTicketItemChange_.bind(this));
107     },
108
109     /** @override */
110     exitDocument: function() {
111       print_preview.Component.prototype.exitDocument.call(this);
112       this.customInput_ = null;
113       this.customRadio_ = null;
114       this.allRadio_ = null;
115       this.customHintEl_ = null;
116     },
117
118     /** @override */
119     decorateInternal: function() {
120       this.customInput_ = this.getElement().getElementsByClassName(
121           PageSettings.Classes_.CUSTOM_INPUT)[0];
122       this.allRadio_ = this.getElement().getElementsByClassName(
123           PageSettings.Classes_.ALL_RADIO)[0];
124       this.customRadio_ = this.getElement().getElementsByClassName(
125           PageSettings.Classes_.CUSTOM_RADIO)[0];
126       this.customHintEl_ = this.getElement().getElementsByClassName(
127           PageSettings.Classes_.CUSTOM_HINT)[0];
128       this.customHintEl_.textContent = localStrings.getStringF(
129           'pageRangeInstruction',
130           localStrings.getString('examplePageRangeText'));
131     },
132
133     /**
134      * @param {boolean} Whether the custom hint is visible.
135      * @private
136      */
137     setInvalidStateVisible_: function(isVisible) {
138       if (isVisible) {
139         this.customInput_.classList.add('invalid');
140         this.customHintEl_.setAttribute('aria-hidden', 'false');
141         fadeInElement(this.customHintEl_);
142       } else {
143         this.customInput_.classList.remove('invalid');
144         fadeOutElement(this.customHintEl_);
145         this.customHintEl_.setAttribute('aria-hidden', 'true');
146       }
147     },
148
149     /**
150      * Called when the all radio button is clicked. Updates the print ticket.
151      * @private
152      */
153     onAllRadioClick_: function() {
154       this.pageRangeTicketItem_.updateValue(null);
155     },
156
157     /**
158      * Called when the custom radio button is clicked. Updates the print ticket.
159      * @private
160      */
161     onCustomRadioClick_: function() {
162       this.customInput_.focus();
163     },
164
165     /**
166      * Called when the custom input is blurred. Enables the all radio button if
167      * the custom input is empty.
168      * @private
169      */
170     onCustomInputBlur_: function() {
171       if (this.customInput_.value == '') {
172         this.allRadio_.checked = true;
173       }
174     },
175
176     /**
177      * Called when the custom input is focused.
178      * @private
179      */
180     onCustomInputFocus_: function() {
181       this.customRadio_.checked = true;
182       this.pageRangeTicketItem_.updateValue(this.customInput_.value);
183     },
184
185     /**
186      * Called when a key is pressed on the custom input.
187      * @param {Event} event Contains the key that was pressed.
188      * @private
189      */
190     onCustomInputKeyUp_: function(event) {
191       if (this.customInputTimeout_) {
192         clearTimeout(this.customInputTimeout_);
193       }
194       if (event.keyIdentifier == 'Enter') {
195         this.pageRangeTicketItem_.updateValue(this.customInput_.value);
196       } else {
197         this.customRadio_.checked = true;
198         this.customInputTimeout_ = setTimeout(
199             this.onCustomInputTimeout_.bind(this),
200             PageSettings.CUSTOM_INPUT_DELAY_);
201       }
202     },
203
204     /**
205      * Called after a delay following a key press in the custom input.
206      * @private
207      */
208     onCustomInputTimeout_: function() {
209       this.customInputTimeout_ = null;
210       if (this.customRadio_.checked) {
211         this.pageRangeTicketItem_.updateValue(this.customInput_.value);
212       }
213     },
214
215     /**
216      * Called when the print ticket changes. Updates the state of the component.
217      * @private
218      */
219     onPageRangeTicketItemChange_: function() {
220       if (this.pageRangeTicketItem_.isCapabilityAvailable()) {
221         var pageRangeStr = this.pageRangeTicketItem_.getValue();
222         if (pageRangeStr || this.customRadio_.checked) {
223           if (!document.hasFocus() ||
224               document.activeElement != this.customInput_) {
225             this.customInput_.value = pageRangeStr;
226           }
227           this.customRadio_.checked = true;
228           this.setInvalidStateVisible_(!this.pageRangeTicketItem_.isValid());
229         } else {
230           this.allRadio_.checked = true;
231           this.setInvalidStateVisible_(false);
232         }
233         fadeInOption(this.getElement());
234       } else {
235         fadeOutOption(this.getElement());
236       }
237     }
238   };
239
240   // Export
241   return {
242     PageSettings: PageSettings
243   };
244 });