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 renders a destination item in a destination list.
10 * @param {!cr.EventTarget} eventTarget Event target to dispatch selection
12 * @param {!print_preview.Destination} destination Destination data object to
14 * @param {RegExp} query Active filter query.
16 * @extends {print_preview.Component}
18 function DestinationListItem(eventTarget, destination, query) {
19 print_preview.Component.call(this);
22 * Event target to dispatch selection events to.
23 * @type {!cr.EventTarget}
26 this.eventTarget_ = eventTarget;
29 * Destination that the list item renders.
30 * @type {!print_preview.Destination}
33 this.destination_ = destination;
36 * Active filter query text.
43 * FedEx terms-of-service widget or {@code null} if this list item does not
44 * render the FedEx Office print destination.
45 * @type {print_preview.FedexTos}
48 this.fedexTos_ = null;
52 * Event types dispatched by the destination list item.
55 DestinationListItem.EventType = {
56 // Dispatched when the list item is activated.
57 SELECT: 'print_preview.DestinationListItem.SELECT',
58 REGISTER_PROMO_CLICKED:
59 'print_preview.DestinationListItem.REGISTER_PROMO_CLICKED'
62 DestinationListItem.prototype = {
63 __proto__: print_preview.Component.prototype,
66 createDom: function() {
67 this.setElementInternal(this.cloneTemplateInternal(
68 'destination-list-item-template'));
73 enterDocument: function() {
74 print_preview.Component.prototype.enterDocument.call(this);
75 this.tracker.add(this.getElement(), 'click', this.onActivate_.bind(this));
77 this.getElement(), 'keydown', this.onKeyDown_.bind(this));
79 this.getChildElement('.register-promo-button'),
81 this.onRegisterPromoClicked_.bind(this));
84 /** @return {!print_preiew.Destination} */
86 return this.destination_;
90 * Updates the list item UI state.
91 * @param {!print_preview.Destination} destination Destination data object
93 * @param {RegExp} query Active filter query.
95 update: function(destination, query) {
96 this.destination_ = destination;
102 * Initializes the element with destination's info.
105 updateUi_: function() {
106 var iconImg = this.getChildElement('.destination-list-item-icon');
107 iconImg.src = this.destination_.iconUrl;
109 var nameEl = this.getChildElement('.destination-list-item-name');
110 var textContent = this.destination_.displayName;
112 nameEl.textContent = '';
113 // When search query is specified, make it obvious why this particular
114 // printer made it to the list. Display name is always visible, even if
115 // it does not match the search query.
116 this.addTextWithHighlight_(nameEl, textContent);
117 // Show the first matching property.
118 this.destination_.extraPropertiesToMatch.some(function(property) {
119 if (property.match(this.query_)) {
120 var hintSpan = document.createElement('span');
121 hintSpan.className = 'search-hint';
122 nameEl.appendChild(hintSpan);
123 this.addTextWithHighlight_(hintSpan, property);
124 // Add the same property to the element title.
125 textContent += ' (' + property + ')';
130 // Show just the display name and nothing else to lessen visual clutter.
131 nameEl.textContent = textContent;
133 nameEl.title = textContent;
135 if (this.destination_.isExtension) {
136 var extensionNameEl = this.getChildElement('.extension-name');
137 var extensionName = this.destination_.extensionName;
138 extensionNameEl.title = this.destination_.extensionName;
140 extensionNameEl.textContent = '';
141 this.addTextWithHighlight_(extensionNameEl, extensionName);
143 extensionNameEl.textContent = this.destination_.extensionName;
146 var extensionIconEl = this.getChildElement('.extension-icon');
147 extensionIconEl.style.backgroundImage = '-webkit-image-set(' +
148 'url(chrome://extension-icon/' +
149 this.destination_.extensionId + '/24/1) 1x,' +
150 'url(chrome://extension-icon/' +
151 this.destination_.extensionId + '/48/1) 2x)';
152 extensionIconEl.title = loadTimeData.getStringF(
153 'extensionDestinationIconTooltip',
154 this.destination_.extensionName);
155 extensionIconEl.onclick = this.onExtensionIconClicked_.bind(this);
156 extensionIconEl.onkeydown = this.onExtensionIconKeyDown_.bind(this);
159 var extensionIndicatorEl =
160 this.getChildElement('.extension-controlled-indicator');
161 setIsVisible(extensionIndicatorEl, this.destination_.isExtension);
163 // Initialize the element which renders the destination's offline status.
164 this.getElement().classList.toggle('stale', this.destination_.isOffline);
165 var offlineStatusEl = this.getChildElement('.offline-status');
166 offlineStatusEl.textContent = this.destination_.offlineStatusText;
167 setIsVisible(offlineStatusEl, this.destination_.isOffline);
169 // Initialize registration promo element for Privet unregistered printers.
171 this.getChildElement('.register-promo'),
172 this.destination_.connectionStatus ==
173 print_preview.Destination.ConnectionStatus.UNREGISTERED);
177 * Adds text to parent element wrapping search query matches in highlighted
179 * @param {!Element} parent Element to build the text in.
180 * @param {string} text The text string to highlight segments in.
183 addTextWithHighlight_: function(parent, text) {
184 var sections = text.split(this.query_);
185 for (var i = 0; i < sections.length; ++i) {
187 parent.appendChild(document.createTextNode(sections[i]));
189 var span = document.createElement('span');
190 span.className = 'destination-list-item-query-highlight';
191 span.textContent = sections[i];
192 parent.appendChild(span);
198 * Called when the destination item is activated. Dispatches a SELECT event
199 * on the given event target.
202 onActivate_: function() {
203 if (this.destination_.id ==
204 print_preview.Destination.GooglePromotedId.FEDEX &&
205 !this.destination_.isTosAccepted) {
206 if (!this.fedexTos_) {
207 this.fedexTos_ = new print_preview.FedexTos();
208 this.fedexTos_.render(this.getElement());
211 print_preview.FedexTos.EventType.AGREE,
212 this.onTosAgree_.bind(this));
214 this.fedexTos_.setIsVisible(true);
215 } else if (this.destination_.connectionStatus !=
216 print_preview.Destination.ConnectionStatus.UNREGISTERED) {
217 var selectEvt = new Event(DestinationListItem.EventType.SELECT);
218 selectEvt.destination = this.destination_;
219 this.eventTarget_.dispatchEvent(selectEvt);
224 * Called when the key is pressed on the destination item. Dispatches a
225 * SELECT event when Enter is pressed.
226 * @param {KeyboardEvent} e Keyboard event to process.
229 onKeyDown_: function(e) {
230 if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
231 if (e.keyCode == 13) {
232 var activeElementTag = document.activeElement ?
233 document.activeElement.tagName.toUpperCase() : '';
234 if (activeElementTag == 'LI') {
244 * Called when the user agrees to the print destination's terms-of-service.
245 * Selects the print destination that was agreed to.
248 onTosAgree_: function() {
249 var selectEvt = new Event(DestinationListItem.EventType.SELECT);
250 selectEvt.destination = this.destination_;
251 this.eventTarget_.dispatchEvent(selectEvt);
255 * Called when the registration promo is clicked.
258 onRegisterPromoClicked_: function() {
259 var promoClickedEvent = new Event(
260 DestinationListItem.EventType.REGISTER_PROMO_CLICKED);
261 promoClickedEvent.destination = this.destination_;
262 this.eventTarget_.dispatchEvent(promoClickedEvent);
266 * Handles click and 'Enter' key down events for the extension icon element.
267 * It opens extensions page with the extension associated with the
268 * destination highlighted.
269 * @param {MouseEvent|KeyboardEvent} e The event to handle.
272 onExtensionIconClicked_: function(e) {
274 window.open('chrome://extensions?id=' + this.destination_.extensionId);
278 * Handles key down event for the extensin icon element. Keys different than
279 * 'Enter' are ignored.
280 * @param {KeyboardEvent} e The event to handle.
283 onExtensionIconKeyDown_: function(e) {
284 if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey)
286 if (e.keyCode != 13 /* Enter */)
288 this.onExtensionIconClicked_(event);
294 DestinationListItem: DestinationListItem