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.
5 cr.define('print_preview', function() {
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
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.
18 * @extends {print_preview.Component}
20 function DestinationList(eventTarget, title, opt_actionLinkLabel) {
21 print_preview.Component.call(this);
24 * Event target to pass to destination items for dispatching SELECT events.
25 * @type {!cr.EventTarget}
28 this.eventTarget_ = eventTarget;
31 * Title of the destination list.
38 * Label of the action link.
42 this.actionLinkLabel_ = opt_actionLinkLabel || null;
45 * Backing store for the destination list.
46 * @type {!Array.<print_preview.Destination>}
49 this.destinations_ = [];
52 * Current query used for filtering.
59 * Whether the destination list is fully expanded.
63 this.isShowAll_ = false;
66 * Maximum number of destinations before showing the "Show All..." button.
70 this.shortListSize_ = DestinationList.DEFAULT_SHORT_LIST_SIZE_;
74 * Enumeration of event types dispatched by the destination list.
77 DestinationList.EventType = {
78 // Dispatched when the action linked is activated.
79 ACTION_LINK_ACTIVATED: 'print_preview.DestinationList.ACTION_LINK_ACTIVATED'
83 * Default maximum number of destinations before showing the "Show All..."
89 DestinationList.DEFAULT_SHORT_LIST_SIZE_ = 4;
92 * Height of a destination list item in pixels.
97 DestinationList.HEIGHT_OF_ITEM_ = 30;
99 DestinationList.prototype = {
100 __proto__: print_preview.Component.prototype,
102 /** @param {boolean} isShowAll Whether the show-all button is activated. */
103 setIsShowAll: function(isShowAll) {
104 this.isShowAll_ = isShowAll;
105 this.renderDestinations_();
109 * @return {number} Size of list when destination list is in collapsed
110 * mode (a.k.a non-show-all mode).
112 getShortListSize: function() {
113 return this.shortListSize_;
116 /** @return {number} Count of the destinations in the list. */
117 getDestinationsCount: function() {
118 return this.destinations_.length;
122 * Gets estimated height of the destination list for the given number of
124 * @param {number} Number of items to render in the destination list.
125 * @return {number} Height (in pixels) of the destination list.
127 getEstimatedHeightInPixels: function(numItems) {
128 numItems = Math.min(numItems, this.destinations_.length);
130 this.getChildElement('.destination-list > header').offsetHeight;
131 return headerHeight + (numItems > 0 ?
132 numItems * DestinationList.HEIGHT_OF_ITEM_ :
133 // To account for "No destinations found" message.
134 DestinationList.HEIGHT_OF_ITEM_);
137 /** @param {boolean} isVisible Whether the throbber is visible. */
138 setIsThrobberVisible: function(isVisible) {
139 setIsVisible(this.getChildElement('.throbber-container'), isVisible);
143 * @param {number} size Size of list when destination list is in collapsed
144 * mode (a.k.a non-show-all mode).
146 updateShortListSize: function(size) {
147 size = Math.max(1, Math.min(size, this.destinations_.length));
148 if (size == 1 && this.destinations_.length > 1) {
149 // If this is the case, we will only show the "Show All" button and
150 // nothing else. Increment the short list size by one so that we can see
151 // at least one print destination.
154 this.setShortListSizeInternal(size);
158 createDom: function() {
159 this.setElementInternal(this.cloneTemplateInternal(
160 'destination-list-template'));
161 this.getChildElement('.title').textContent = this.title_;
162 if (this.actionLinkLabel_) {
163 var actionLinkEl = this.getChildElement('.action-link');
164 actionLinkEl.textContent = this.actionLinkLabel_;
165 setIsVisible(actionLinkEl, true);
170 enterDocument: function() {
171 print_preview.Component.prototype.enterDocument.call(this);
173 this.getChildElement('.action-link'),
175 this.onActionLinkClick_.bind(this));
177 this.getChildElement('.show-all-button'),
179 this.setIsShowAll.bind(this, true));
183 * Updates the destinations to render in the destination list.
184 * @param {!Array.<print_preview.Destination>} destinations Destinations to
187 updateDestinations: function(destinations) {
188 this.destinations_ = destinations;
189 this.renderDestinations_();
192 /** @param {?string} query Query to update the filter with. */
193 updateSearchQuery: function(query) {
197 // Generate regexp-safe query by escaping metacharacters.
198 var safeQuery = query.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
199 this.query_ = new RegExp('(' + safeQuery + ')', 'ig');
201 this.renderDestinations_();
205 * @param {string} text Text to set the action link to.
208 setActionLinkTextInternal: function(text) {
209 this.actionLinkLabel_ = text;
210 this.getChildElement('.action-link').textContent = text;
214 * Sets the short list size without constraints.
217 setShortListSizeInternal: function(size) {
218 this.shortListSize_ = size;
219 this.renderDestinations_();
223 * Renders all destinations in the given list.
224 * @param {!Array.<print_preview.Destination>} destinations List of
225 * destinations to render.
228 renderListInternal: function(destinations) {
229 setIsVisible(this.getChildElement('.no-destinations-message'),
230 destinations.length == 0);
231 setIsVisible(this.getChildElement('.destination-list > footer'), false);
232 var numItems = destinations.length;
233 if (destinations.length > this.shortListSize_ && !this.isShowAll_) {
234 numItems = this.shortListSize_ - 1;
235 this.getChildElement('.total').textContent =
236 localStrings.getStringF('destinationCount', destinations.length);
237 setIsVisible(this.getChildElement('.destination-list > footer'), true);
239 for (var i = 0; i < numItems; i++) {
240 var destListItem = new print_preview.DestinationListItem(
241 this.eventTarget_, destinations[i], this.query_);
242 this.addChild(destListItem);
243 destListItem.render(this.getChildElement('.destination-list > ul'));
248 * Renders all destinations in the list that match the current query. For
249 * each render, all old destination items are first removed.
252 renderDestinations_: function() {
253 this.removeChildren();
256 this.renderListInternal(this.destinations_);
258 var filteredDests = this.destinations_.filter(function(destination) {
259 return destination.matches(this.query_);
261 this.renderListInternal(filteredDests);
266 * Called when the action link is clicked. Dispatches an
267 * ACTION_LINK_ACTIVATED event.
270 onActionLinkClick_: function() {
271 cr.dispatchSimpleEvent(this,
272 DestinationList.EventType.ACTION_LINK_ACTIVATED);
278 DestinationList: DestinationList