Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / print_preview / settings / advanced_settings / advanced_settings_item.js
1 // Copyright 2014 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    * Component that renders a destination item in a destination list.
10    * @param {!cr.EventTarget} eventTarget Event target to dispatch selection
11    *     events to.
12    * @param {!print_preview.PrintTicketStore} printTicketStore Contains the
13    *     print ticket to print.
14    * @param {!Object} capability Capability to render.
15    * @constructor
16    * @extends {print_preview.Component}
17    */
18   function AdvancedSettingsItem(eventTarget, printTicketStore, capability) {
19     print_preview.Component.call(this);
20
21     /**
22      * Event target to dispatch selection events to.
23      * @private {!cr.EventTarget}
24      */
25     this.eventTarget_ = eventTarget;
26
27     /**
28      * Contains the print ticket to print.
29      * @private {!print_preview.PrintTicketStore}
30      */
31     this.printTicketStore_ = printTicketStore;
32
33     /**
34      * Capability this component renders.
35      * @private {!Object}
36      */
37     this.capability_ = capability;
38
39     /**
40      * Value selected by user. {@code null}, if user has not changed the default
41      * value yet (still, the value can be the default one, if it is what user
42      * selected).
43      * @private {?string}
44      */
45     this.selectedValue_ = null;
46
47     /**
48      * Active filter query.
49      * @private {RegExp}
50      */
51     this.query_ = null;
52
53     /**
54      * Search hint for the control.
55      * @private {print_preview.SearchBubble}
56      */
57     this.searchBubble_ = null;
58
59     /** @private {!EventTracker} */
60     this.tracker_ = new EventTracker();
61   };
62
63   AdvancedSettingsItem.prototype = {
64     __proto__: print_preview.Component.prototype,
65
66     /** @override */
67     createDom: function() {
68       this.setElementInternal(this.cloneTemplateInternal(
69           'advanced-settings-item-template'));
70
71       this.tracker_.add(
72           this.select_, 'change', this.onSelectChange_.bind(this));
73       this.tracker_.add(this.text_, 'input', this.onTextInput_.bind(this));
74
75       this.initializeValue_();
76
77       this.renderCapability_();
78     },
79
80     /**
81      * ID of the corresponding vendor capability.
82      * @return {string}
83      */
84     get id() {
85       return this.capability_.id;
86     },
87
88     /**
89      * Currently selected value.
90      * @return {string}
91      */
92     get selectedValue() {
93       return this.selectedValue_ || '';
94     },
95
96     /**
97      * Whether the corresponding ticket item was changed or not.
98      * @return {boolean}
99      */
100     isModified: function() {
101       return !!this.selectedValue_;
102     },
103
104     /** @param {RegExp} query Query to update the filter with. */
105     updateSearchQuery: function(query) {
106       this.query_ = query;
107       this.renderCapability_();
108     },
109
110     get searchBubbleShown() {
111       return getIsVisible(this.getElement()) && !!this.searchBubble_;
112     },
113
114     /**
115      * @return {HTMLSelectElement} Select element.
116      * @private
117      */
118     get select_() {
119       return this.getChildElement(
120           '.advanced-settings-item-value-select-control');
121     },
122
123     /**
124      * @return {HTMLSelectElement} Text element.
125      * @private
126      */
127     get text_() {
128       return this.getChildElement('.advanced-settings-item-value-text-control');
129     },
130
131     /**
132      * Called when the select element value is changed.
133      * @private
134      */
135     onSelectChange_: function() {
136       this.selectedValue_ = this.select_.value;
137       this.capability_.select_cap.option.some(function(option) {
138         if (this.select_.value == option.value && option.is_default)
139           this.selectedValue_ = null;
140         return this.select_.value == option.value || option.is_default;
141       }.bind(this));
142     },
143
144     /**
145      * Called when the text element value is changed.
146      * @private
147      */
148     onTextInput_: function() {
149       this.selectedValue_ = this.text_.value || null;
150
151       if (this.query_) {
152         var optionMatches = (this.selectedValue_ || '').match(this.query_);
153         // Even if there's no match anymore, keep the item visible to do not
154         // surprise user.
155         if (optionMatches)
156           this.showSearchBubble_(optionMatches[0]);
157         else
158           this.hideSearchBubble_();
159       }
160     },
161
162     /**
163      * Renders capability properties according to the current state.
164      * @private
165      */
166     renderCapability_: function() {
167       var textContent = this.capability_.display_name;
168       var nameMatches = this.query_ ? !!textContent.match(this.query_) : true;
169       var optionMatches = null;
170       if (this.query_) {
171         if (this.capability_.type == 'SELECT') {
172           this.capability_.select_cap.option.some(function(option) {
173             optionMatches = (option.display_name || '').match(this.query_);
174             return !!optionMatches;
175           }.bind(this));
176         } else {
177           optionMatches = (this.text_.value || '').match(this.query_);
178         }
179       }
180       var matches = nameMatches || optionMatches;
181
182       if (!matches || !optionMatches)
183         this.hideSearchBubble_();
184
185       setIsVisible(this.getElement(), matches);
186       if (!matches)
187         return;
188
189       var nameEl = this.getChildElement('.advanced-settings-item-label');
190       if (this.query_) {
191         nameEl.textContent = '';
192         this.addTextWithHighlight_(nameEl, textContent);
193       } else {
194         nameEl.textContent = textContent;
195       }
196       nameEl.title = textContent;
197
198       if (optionMatches)
199         this.showSearchBubble_(optionMatches[0]);
200     },
201
202     /**
203      * Shows search bubble for this element.
204      * @param {string} text Text to show in the search bubble.
205      * @private
206      */
207     showSearchBubble_: function(text) {
208       var element =
209           this.capability_.type == 'SELECT' ? this.select_ : this.text_;
210       if (!this.searchBubble_) {
211         this.searchBubble_ = new print_preview.SearchBubble(text);
212         this.searchBubble_.attachTo(element);
213       } else {
214         this.searchBubble_.content = text;
215       }
216     },
217
218     /**
219      * Hides search bubble associated with this element.
220      * @private
221      */
222     hideSearchBubble_: function() {
223       if (this.searchBubble_) {
224         this.searchBubble_.dispose();
225         this.searchBubble_ = null;
226       }
227     },
228
229     /**
230      * Initializes the element's value control.
231      * @private
232      */
233     initializeValue_: function() {
234       this.selectedValue_ =
235           this.printTicketStore_.vendorItems.ticketItems[this.id] || null;
236
237       if (this.capability_.type == 'SELECT')
238         this.initializeSelectValue_();
239       else
240         this.initializeTextValue_();
241     },
242
243     /**
244      * Initializes the select element.
245      * @private
246      */
247     initializeSelectValue_: function() {
248       setIsVisible(
249         this.getChildElement('.advanced-settings-item-value-select'), true);
250       var selectEl = this.select_;
251       var indexToSelect = 0;
252       this.capability_.select_cap.option.forEach(function(option, index) {
253         var item = document.createElement('option');
254         item.text = option.display_name;
255         item.value = option.value;
256         if (option.is_default)
257           indexToSelect = index;
258         selectEl.appendChild(item);
259       });
260       for (var i = 0, option; option = selectEl.options[i]; i++) {
261         if (option.value == this.selectedValue_) {
262           indexToSelect = i;
263           break;
264         }
265       }
266       selectEl.selectedIndex = indexToSelect;
267     },
268
269     /**
270      * Initializes the text element.
271      * @private
272      */
273     initializeTextValue_: function() {
274       setIsVisible(
275           this.getChildElement('.advanced-settings-item-value-text'), true);
276       this.text_.value = this.selectedValue;
277     },
278
279     /**
280      * Adds text to parent element wrapping search query matches in highlighted
281      * spans.
282      * @param {!Element} parent Element to build the text in.
283      * @param {string} text The text string to highlight segments in.
284      * @private
285      */
286     addTextWithHighlight_: function(parent, text) {
287       text.split(this.query_).forEach(function(section, i) {
288         if (i % 2 == 0) {
289           parent.appendChild(document.createTextNode(section));
290         } else {
291           var span = document.createElement('span');
292           span.className = 'advanced-settings-item-query-highlight';
293           span.textContent = section;
294           parent.appendChild(span);
295         }
296       });
297     }
298   };
299
300   // Export
301   return {
302     AdvancedSettingsItem: AdvancedSettingsItem
303   };
304 });