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