- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / print_preview / search / destination_list.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    * Component that displays a list of destinations with a heading, action link,
10    * and "Show All..." button. An event is dispatched when the action link is
11    * activated.
12    * @param {!cr.EventTarget} eventTarget Event target to pass to destination
13    *     items for dispatching SELECT events.
14    * @param {string} title Title of the destination list.
15    * @param {string=} opt_actionLinkLabel Optional label of the action link. If
16    *     no label is provided, the action link will not be shown.
17    * @constructor
18    * @extends {print_preview.Component}
19    */
20   function DestinationList(eventTarget, title, opt_actionLinkLabel) {
21     print_preview.Component.call(this);
22
23     /**
24      * Event target to pass to destination items for dispatching SELECT events.
25      * @type {!cr.EventTarget}
26      * @private
27      */
28     this.eventTarget_ = eventTarget;
29
30     /**
31      * Title of the destination list.
32      * @type {string}
33      * @private
34      */
35     this.title_ = title;
36
37     /**
38      * Label of the action link.
39      * @type {?string}
40      * @private
41      */
42     this.actionLinkLabel_ = opt_actionLinkLabel || null;
43
44     /**
45      * Backing store for the destination list.
46      * @type {!Array.<print_preview.Destination>}
47      * @private
48      */
49     this.destinations_ = [];
50
51     /**
52      * Current query used for filtering.
53      * @type {?string}
54      * @private
55      */
56     this.query_ = null;
57
58     /**
59      * Whether the destination list is fully expanded.
60      * @type {boolean}
61      * @private
62      */
63     this.isShowAll_ = false;
64
65     /**
66      * Maximum number of destinations before showing the "Show All..." button.
67      * @type {number}
68      * @private
69      */
70     this.shortListSize_ = DestinationList.DEFAULT_SHORT_LIST_SIZE_;
71   };
72
73   /**
74    * Enumeration of event types dispatched by the destination list.
75    * @enum {string}
76    */
77   DestinationList.EventType = {
78     // Dispatched when the action linked is activated.
79     ACTION_LINK_ACTIVATED: 'print_preview.DestinationList.ACTION_LINK_ACTIVATED'
80   };
81
82   /**
83    * Default maximum number of destinations before showing the "Show All..."
84    * button.
85    * @type {number}
86    * @const
87    * @private
88    */
89   DestinationList.DEFAULT_SHORT_LIST_SIZE_ = 4;
90
91   /**
92    * Height of a destination list item in pixels.
93    * @type {number}
94    * @const
95    * @private
96    */
97   DestinationList.HEIGHT_OF_ITEM_ = 30;
98
99   DestinationList.prototype = {
100     __proto__: print_preview.Component.prototype,
101
102     /** @param {boolean} isShowAll Whether the show-all button is activated. */
103     setIsShowAll: function(isShowAll) {
104       this.isShowAll_ = isShowAll;
105       this.renderDestinations_();
106     },
107
108     /**
109      * @return {number} Size of list when destination list is in collapsed
110      *     mode (a.k.a non-show-all mode).
111      */
112     getShortListSize: function() {
113       return this.shortListSize_;
114     },
115
116     /** @return {number} Count of the destinations in the list. */
117     getDestinationsCount: function() {
118       return this.destinations_.length;
119     },
120
121     /**
122      * Gets estimated height of the destination list for the given number of
123      * items.
124      * @param {number} Number of items to render in the destination list.
125      * @return {number} Height (in pixels) of the destination list.
126      */
127     getEstimatedHeightInPixels: function(numItems) {
128       numItems = Math.min(numItems, this.destinations_.length);
129       var headerHeight =
130           this.getChildElement('.destination-list > header').offsetHeight;
131       var throbberHeight =
132           getIsVisible(this.getChildElement('.throbber-container')) ?
133               DestinationList.HEIGHT_OF_ITEM_ : 0;
134       return headerHeight + numItems * DestinationList.HEIGHT_OF_ITEM_ +
135           throbberHeight;
136     },
137
138     /** @param {boolean} isVisible Whether the throbber is visible. */
139     setIsThrobberVisible: function(isVisible) {
140       setIsVisible(this.getChildElement('.throbber-container'), isVisible);
141     },
142
143     /**
144      * @param {number} size Size of list when destination list is in collapsed
145      *     mode (a.k.a non-show-all mode).
146      */
147     updateShortListSize: function(size) {
148       size = Math.max(1, Math.min(size, this.destinations_.length));
149       if (size == 1 && this.destinations_.length > 1) {
150         // If this is the case, we will only show the "Show All" button and
151         // nothing else. Increment the short list size by one so that we can see
152         // at least one print destination.
153         size++;
154       }
155       this.setShortListSizeInternal(size);
156     },
157
158     /** @override */
159     createDom: function() {
160       this.setElementInternal(this.cloneTemplateInternal(
161           'destination-list-template'));
162       this.getChildElement('.title').textContent = this.title_;
163       if (this.actionLinkLabel_) {
164         var actionLinkEl = this.getChildElement('.action-link');
165         actionLinkEl.textContent = this.actionLinkLabel_;
166         setIsVisible(actionLinkEl, true);
167       }
168     },
169
170     /** @override */
171     enterDocument: function() {
172       print_preview.Component.prototype.enterDocument.call(this);
173       this.tracker.add(
174           this.getChildElement('.action-link'),
175           'click',
176           this.onActionLinkClick_.bind(this));
177       this.tracker.add(
178           this.getChildElement('.show-all-button'),
179           'click',
180           this.setIsShowAll.bind(this, true));
181     },
182
183     /**
184      * Updates the destinations to render in the destination list.
185      * @param {!Array.<print_preview.Destination>} destinations Destinations to
186      *     render.
187      */
188     updateDestinations: function(destinations) {
189       this.destinations_ = destinations;
190       this.renderDestinations_();
191     },
192
193     /** @param {?string} query Query to update the filter with. */
194     updateSearchQuery: function(query) {
195       this.query_ = query;
196       this.renderDestinations_();
197     },
198
199     /**
200      * @param {string} text Text to set the action link to.
201      * @protected
202      */
203     setActionLinkTextInternal: function(text) {
204       this.actionLinkLabel_ = text;
205       this.getChildElement('.action-link').textContent = text;
206     },
207
208     /**
209      * Sets the short list size without constraints.
210      * @protected
211      */
212     setShortListSizeInternal: function(size) {
213       this.shortListSize_ = size;
214       this.renderDestinations_();
215     },
216
217     /**
218      * Renders all destinations in the given list.
219      * @param {!Array.<print_preview.Destination>} destinations List of
220      *     destinations to render.
221      * @protected
222      */
223     renderListInternal: function(destinations) {
224       setIsVisible(this.getChildElement('.no-destinations-message'),
225                    destinations.length == 0);
226       setIsVisible(this.getChildElement('.destination-list > footer'), false);
227       var numItems = destinations.length;
228       if (destinations.length > this.shortListSize_ && !this.isShowAll_) {
229         numItems = this.shortListSize_ - 1;
230         this.getChildElement('.total').textContent =
231             localStrings.getStringF('destinationCount', destinations.length);
232         setIsVisible(this.getChildElement('.destination-list > footer'), true);
233       }
234       for (var i = 0; i < numItems; i++) {
235         var destListItem = new print_preview.DestinationListItem(
236             this.eventTarget_, destinations[i]);
237         this.addChild(destListItem);
238         destListItem.render(this.getChildElement('.destination-list > ul'));
239       }
240     },
241
242     /**
243      * Renders all destinations in the list that match the current query. For
244      * each render, all old destination items are first removed.
245      * @private
246      */
247     renderDestinations_: function() {
248       this.removeChildren();
249
250       var filteredDests = [];
251       this.destinations_.forEach(function(destination) {
252         if (!this.query_ || destination.matches(this.query_)) {
253           filteredDests.push(destination);
254         }
255       }, this);
256
257       this.renderListInternal(filteredDests);
258     },
259
260     /**
261      * Called when the action link is clicked. Dispatches an
262      * ACTION_LINK_ACTIVATED event.
263      * @private
264      */
265     onActionLinkClick_: function() {
266       cr.dispatchSimpleEvent(this,
267                              DestinationList.EventType.ACTION_LINK_ACTIVATED);
268     }
269   };
270
271   // Export
272   return {
273     DestinationList: DestinationList
274   };
275 });